1a17ae4c3SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2212188a5SHendrik Brueckner /* 3212188a5SHendrik Brueckner * Performance event support for s390x - CPU-measurement Counter Facility 4212188a5SHendrik Brueckner * 5*1e99c242SThomas Richter * Copyright IBM Corp. 2012, 2023 646a984ffSThomas Richter * Author(s): Hendrik Brueckner <brueckner@linux.ibm.com> 7a029a4eaSThomas Richter * Thomas Richter <tmricht@linux.ibm.com> 8212188a5SHendrik Brueckner */ 9212188a5SHendrik Brueckner #define KMSG_COMPONENT "cpum_cf" 10212188a5SHendrik Brueckner #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11212188a5SHendrik Brueckner 12212188a5SHendrik Brueckner #include <linux/kernel.h> 13212188a5SHendrik Brueckner #include <linux/kernel_stat.h> 14212188a5SHendrik Brueckner #include <linux/percpu.h> 15212188a5SHendrik Brueckner #include <linux/notifier.h> 16212188a5SHendrik Brueckner #include <linux/init.h> 17212188a5SHendrik Brueckner #include <linux/export.h> 18a029a4eaSThomas Richter #include <linux/miscdevice.h> 19*1e99c242SThomas Richter #include <linux/perf_event.h> 20a029a4eaSThomas Richter 21*1e99c242SThomas Richter #include <asm/cpu_mf.h> 22a029a4eaSThomas Richter #include <asm/hwctrset.h> 23a029a4eaSThomas Richter #include <asm/debug.h> 24a029a4eaSThomas Richter 25*1e99c242SThomas Richter enum cpumf_ctr_set { 26*1e99c242SThomas Richter CPUMF_CTR_SET_BASIC = 0, /* Basic Counter Set */ 27*1e99c242SThomas Richter CPUMF_CTR_SET_USER = 1, /* Problem-State Counter Set */ 28*1e99c242SThomas Richter CPUMF_CTR_SET_CRYPTO = 2, /* Crypto-Activity Counter Set */ 29*1e99c242SThomas Richter CPUMF_CTR_SET_EXT = 3, /* Extended Counter Set */ 30*1e99c242SThomas Richter CPUMF_CTR_SET_MT_DIAG = 4, /* MT-diagnostic Counter Set */ 31*1e99c242SThomas Richter 32*1e99c242SThomas Richter /* Maximum number of counter sets */ 33*1e99c242SThomas Richter CPUMF_CTR_SET_MAX, 34*1e99c242SThomas Richter }; 35*1e99c242SThomas Richter 36*1e99c242SThomas Richter #define CPUMF_LCCTL_ENABLE_SHIFT 16 37*1e99c242SThomas Richter #define CPUMF_LCCTL_ACTCTL_SHIFT 0 38*1e99c242SThomas Richter 39*1e99c242SThomas Richter static inline void ctr_set_enable(u64 *state, u64 ctrsets) 40*1e99c242SThomas Richter { 41*1e99c242SThomas Richter *state |= ctrsets << CPUMF_LCCTL_ENABLE_SHIFT; 42*1e99c242SThomas Richter } 43*1e99c242SThomas Richter 44*1e99c242SThomas Richter static inline void ctr_set_disable(u64 *state, u64 ctrsets) 45*1e99c242SThomas Richter { 46*1e99c242SThomas Richter *state &= ~(ctrsets << CPUMF_LCCTL_ENABLE_SHIFT); 47*1e99c242SThomas Richter } 48*1e99c242SThomas Richter 49*1e99c242SThomas Richter static inline void ctr_set_start(u64 *state, u64 ctrsets) 50*1e99c242SThomas Richter { 51*1e99c242SThomas Richter *state |= ctrsets << CPUMF_LCCTL_ACTCTL_SHIFT; 52*1e99c242SThomas Richter } 53*1e99c242SThomas Richter 54*1e99c242SThomas Richter static inline void ctr_set_stop(u64 *state, u64 ctrsets) 55*1e99c242SThomas Richter { 56*1e99c242SThomas Richter *state &= ~(ctrsets << CPUMF_LCCTL_ACTCTL_SHIFT); 57*1e99c242SThomas Richter } 58*1e99c242SThomas Richter 59*1e99c242SThomas Richter static inline int ctr_stcctm(enum cpumf_ctr_set set, u64 range, u64 *dest) 60*1e99c242SThomas Richter { 61*1e99c242SThomas Richter switch (set) { 62*1e99c242SThomas Richter case CPUMF_CTR_SET_BASIC: 63*1e99c242SThomas Richter return stcctm(BASIC, range, dest); 64*1e99c242SThomas Richter case CPUMF_CTR_SET_USER: 65*1e99c242SThomas Richter return stcctm(PROBLEM_STATE, range, dest); 66*1e99c242SThomas Richter case CPUMF_CTR_SET_CRYPTO: 67*1e99c242SThomas Richter return stcctm(CRYPTO_ACTIVITY, range, dest); 68*1e99c242SThomas Richter case CPUMF_CTR_SET_EXT: 69*1e99c242SThomas Richter return stcctm(EXTENDED, range, dest); 70*1e99c242SThomas Richter case CPUMF_CTR_SET_MT_DIAG: 71*1e99c242SThomas Richter return stcctm(MT_DIAG_CLEARING, range, dest); 72*1e99c242SThomas Richter case CPUMF_CTR_SET_MAX: 73*1e99c242SThomas Richter return 3; 74*1e99c242SThomas Richter } 75*1e99c242SThomas Richter return 3; 76*1e99c242SThomas Richter } 77*1e99c242SThomas Richter 78*1e99c242SThomas Richter struct cpu_cf_events { 79*1e99c242SThomas Richter struct cpumf_ctr_info info; 80*1e99c242SThomas Richter atomic_t ctr_set[CPUMF_CTR_SET_MAX]; 81*1e99c242SThomas Richter u64 state; /* For perf_event_open SVC */ 82*1e99c242SThomas Richter u64 dev_state; /* For /dev/hwctr */ 83*1e99c242SThomas Richter unsigned int flags; 84*1e99c242SThomas Richter size_t used; /* Bytes used in data */ 85*1e99c242SThomas Richter size_t usedss; /* Bytes used in start/stop */ 86*1e99c242SThomas Richter unsigned char start[PAGE_SIZE]; /* Counter set at event add */ 87*1e99c242SThomas Richter unsigned char stop[PAGE_SIZE]; /* Counter set at event delete */ 88*1e99c242SThomas Richter unsigned char data[PAGE_SIZE]; /* Counter set at /dev/hwctr */ 89*1e99c242SThomas Richter unsigned int sets; /* # Counter set saved in memory */ 90*1e99c242SThomas Richter }; 91*1e99c242SThomas Richter 92*1e99c242SThomas Richter /* Per-CPU event structure for the counter facility */ 93*1e99c242SThomas Richter static DEFINE_PER_CPU(struct cpu_cf_events, cpu_cf_events); 94*1e99c242SThomas Richter 95a029a4eaSThomas Richter static unsigned int cfdiag_cpu_speed; /* CPU speed for CF_DIAG trailer */ 96a029a4eaSThomas Richter static debug_info_t *cf_dbg; 97a029a4eaSThomas Richter 98a029a4eaSThomas Richter #define CF_DIAG_CTRSET_DEF 0xfeef /* Counter set header mark */ 99a029a4eaSThomas Richter /* interval in seconds */ 100a029a4eaSThomas Richter 101a029a4eaSThomas Richter /* Counter sets are stored as data stream in a page sized memory buffer and 102a029a4eaSThomas Richter * exported to user space via raw data attached to the event sample data. 103a029a4eaSThomas Richter * Each counter set starts with an eight byte header consisting of: 104a029a4eaSThomas Richter * - a two byte eye catcher (0xfeef) 105a029a4eaSThomas Richter * - a one byte counter set number 106a029a4eaSThomas Richter * - a two byte counter set size (indicates the number of counters in this set) 107a029a4eaSThomas Richter * - a three byte reserved value (must be zero) to make the header the same 108a029a4eaSThomas Richter * size as a counter value. 109a029a4eaSThomas Richter * All counter values are eight byte in size. 110a029a4eaSThomas Richter * 111a029a4eaSThomas Richter * All counter sets are followed by a 64 byte trailer. 112a029a4eaSThomas Richter * The trailer consists of a: 113a029a4eaSThomas Richter * - flag field indicating valid fields when corresponding bit set 114a029a4eaSThomas Richter * - the counter facility first and second version number 115a029a4eaSThomas Richter * - the CPU speed if nonzero 116a029a4eaSThomas Richter * - the time stamp the counter sets have been collected 117a029a4eaSThomas Richter * - the time of day (TOD) base value 118a029a4eaSThomas Richter * - the machine type. 119a029a4eaSThomas Richter * 120a029a4eaSThomas Richter * The counter sets are saved when the process is prepared to be executed on a 121a029a4eaSThomas Richter * CPU and saved again when the process is going to be removed from a CPU. 122a029a4eaSThomas Richter * The difference of both counter sets are calculated and stored in the event 123a029a4eaSThomas Richter * sample data area. 124a029a4eaSThomas Richter */ 125a029a4eaSThomas Richter struct cf_ctrset_entry { /* CPU-M CF counter set entry (8 byte) */ 126a029a4eaSThomas Richter unsigned int def:16; /* 0-15 Data Entry Format */ 127a029a4eaSThomas Richter unsigned int set:16; /* 16-31 Counter set identifier */ 128a029a4eaSThomas Richter unsigned int ctr:16; /* 32-47 Number of stored counters */ 129a029a4eaSThomas Richter unsigned int res1:16; /* 48-63 Reserved */ 130a029a4eaSThomas Richter }; 131a029a4eaSThomas Richter 132a029a4eaSThomas Richter struct cf_trailer_entry { /* CPU-M CF_DIAG trailer (64 byte) */ 133a029a4eaSThomas Richter /* 0 - 7 */ 134a029a4eaSThomas Richter union { 135a029a4eaSThomas Richter struct { 136a029a4eaSThomas Richter unsigned int clock_base:1; /* TOD clock base set */ 137a029a4eaSThomas Richter unsigned int speed:1; /* CPU speed set */ 138a029a4eaSThomas Richter /* Measurement alerts */ 139a029a4eaSThomas Richter unsigned int mtda:1; /* Loss of MT ctr. data alert */ 140a029a4eaSThomas Richter unsigned int caca:1; /* Counter auth. change alert */ 141a029a4eaSThomas Richter unsigned int lcda:1; /* Loss of counter data alert */ 142a029a4eaSThomas Richter }; 143a029a4eaSThomas Richter unsigned long flags; /* 0-63 All indicators */ 144a029a4eaSThomas Richter }; 145a029a4eaSThomas Richter /* 8 - 15 */ 146a029a4eaSThomas Richter unsigned int cfvn:16; /* 64-79 Ctr First Version */ 147a029a4eaSThomas Richter unsigned int csvn:16; /* 80-95 Ctr Second Version */ 148a029a4eaSThomas Richter unsigned int cpu_speed:32; /* 96-127 CPU speed */ 149a029a4eaSThomas Richter /* 16 - 23 */ 150a029a4eaSThomas Richter unsigned long timestamp; /* 128-191 Timestamp (TOD) */ 151a029a4eaSThomas Richter /* 24 - 55 */ 152a029a4eaSThomas Richter union { 153a029a4eaSThomas Richter struct { 154a029a4eaSThomas Richter unsigned long progusage1; 155a029a4eaSThomas Richter unsigned long progusage2; 156a029a4eaSThomas Richter unsigned long progusage3; 157a029a4eaSThomas Richter unsigned long tod_base; 158a029a4eaSThomas Richter }; 159a029a4eaSThomas Richter unsigned long progusage[4]; 160a029a4eaSThomas Richter }; 161a029a4eaSThomas Richter /* 56 - 63 */ 162a029a4eaSThomas Richter unsigned int mach_type:16; /* Machine type */ 163a029a4eaSThomas Richter unsigned int res1:16; /* Reserved */ 164a029a4eaSThomas Richter unsigned int res2:32; /* Reserved */ 165a029a4eaSThomas Richter }; 166a029a4eaSThomas Richter 167a029a4eaSThomas Richter /* Create the trailer data at the end of a page. */ 168a029a4eaSThomas Richter static void cfdiag_trailer(struct cf_trailer_entry *te) 169a029a4eaSThomas Richter { 170a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 171a029a4eaSThomas Richter struct cpuid cpuid; 172a029a4eaSThomas Richter 173a029a4eaSThomas Richter te->cfvn = cpuhw->info.cfvn; /* Counter version numbers */ 174a029a4eaSThomas Richter te->csvn = cpuhw->info.csvn; 175a029a4eaSThomas Richter 176a029a4eaSThomas Richter get_cpu_id(&cpuid); /* Machine type */ 177a029a4eaSThomas Richter te->mach_type = cpuid.machine; 178a029a4eaSThomas Richter te->cpu_speed = cfdiag_cpu_speed; 179a029a4eaSThomas Richter if (te->cpu_speed) 180a029a4eaSThomas Richter te->speed = 1; 181a029a4eaSThomas Richter te->clock_base = 1; /* Save clock base */ 182a029a4eaSThomas Richter te->tod_base = tod_clock_base.tod; 183a029a4eaSThomas Richter te->timestamp = get_tod_clock_fast(); 184a029a4eaSThomas Richter } 185a029a4eaSThomas Richter 186345d2a4dSThomas Richter /* 187345d2a4dSThomas Richter * Return the maximum possible counter set size (in number of 8 byte counters) 188345d2a4dSThomas Richter * depending on type and model number. 189345d2a4dSThomas Richter */ 190345d2a4dSThomas Richter static size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset, 191345d2a4dSThomas Richter struct cpumf_ctr_info *info) 192345d2a4dSThomas Richter { 193345d2a4dSThomas Richter size_t ctrset_size = 0; 194345d2a4dSThomas Richter 195345d2a4dSThomas Richter switch (ctrset) { 196345d2a4dSThomas Richter case CPUMF_CTR_SET_BASIC: 197345d2a4dSThomas Richter if (info->cfvn >= 1) 198345d2a4dSThomas Richter ctrset_size = 6; 199345d2a4dSThomas Richter break; 200345d2a4dSThomas Richter case CPUMF_CTR_SET_USER: 201345d2a4dSThomas Richter if (info->cfvn == 1) 202345d2a4dSThomas Richter ctrset_size = 6; 203345d2a4dSThomas Richter else if (info->cfvn >= 3) 204345d2a4dSThomas Richter ctrset_size = 2; 205345d2a4dSThomas Richter break; 206345d2a4dSThomas Richter case CPUMF_CTR_SET_CRYPTO: 207345d2a4dSThomas Richter if (info->csvn >= 1 && info->csvn <= 5) 208345d2a4dSThomas Richter ctrset_size = 16; 209345d2a4dSThomas Richter else if (info->csvn == 6 || info->csvn == 7) 210345d2a4dSThomas Richter ctrset_size = 20; 211345d2a4dSThomas Richter break; 212345d2a4dSThomas Richter case CPUMF_CTR_SET_EXT: 213345d2a4dSThomas Richter if (info->csvn == 1) 214345d2a4dSThomas Richter ctrset_size = 32; 215345d2a4dSThomas Richter else if (info->csvn == 2) 216345d2a4dSThomas Richter ctrset_size = 48; 217345d2a4dSThomas Richter else if (info->csvn >= 3 && info->csvn <= 5) 218345d2a4dSThomas Richter ctrset_size = 128; 219345d2a4dSThomas Richter else if (info->csvn == 6 || info->csvn == 7) 220345d2a4dSThomas Richter ctrset_size = 160; 221345d2a4dSThomas Richter break; 222345d2a4dSThomas Richter case CPUMF_CTR_SET_MT_DIAG: 223345d2a4dSThomas Richter if (info->csvn > 3) 224345d2a4dSThomas Richter ctrset_size = 48; 225345d2a4dSThomas Richter break; 226345d2a4dSThomas Richter case CPUMF_CTR_SET_MAX: 227345d2a4dSThomas Richter break; 228345d2a4dSThomas Richter } 229345d2a4dSThomas Richter 230345d2a4dSThomas Richter return ctrset_size; 231345d2a4dSThomas Richter } 232345d2a4dSThomas Richter 233a029a4eaSThomas Richter /* Read a counter set. The counter set number determines the counter set and 234a029a4eaSThomas Richter * the CPUM-CF first and second version number determine the number of 235a029a4eaSThomas Richter * available counters in each counter set. 236a029a4eaSThomas Richter * Each counter set starts with header containing the counter set number and 237a029a4eaSThomas Richter * the number of eight byte counters. 238a029a4eaSThomas Richter * 239a029a4eaSThomas Richter * The functions returns the number of bytes occupied by this counter set 240a029a4eaSThomas Richter * including the header. 241a029a4eaSThomas Richter * If there is no counter in the counter set, this counter set is useless and 242a029a4eaSThomas Richter * zero is returned on this case. 243a029a4eaSThomas Richter * 244a029a4eaSThomas Richter * Note that the counter sets may not be enabled or active and the stcctm 245a029a4eaSThomas Richter * instruction might return error 3. Depending on error_ok value this is ok, 246a029a4eaSThomas Richter * for example when called from cpumf_pmu_start() call back function. 247a029a4eaSThomas Richter */ 248a029a4eaSThomas Richter static size_t cfdiag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset, 249a029a4eaSThomas Richter size_t room, bool error_ok) 250a029a4eaSThomas Richter { 251a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 252a029a4eaSThomas Richter size_t ctrset_size, need = 0; 253a029a4eaSThomas Richter int rc = 3; /* Assume write failure */ 254a029a4eaSThomas Richter 255a029a4eaSThomas Richter ctrdata->def = CF_DIAG_CTRSET_DEF; 256a029a4eaSThomas Richter ctrdata->set = ctrset; 257a029a4eaSThomas Richter ctrdata->res1 = 0; 258a029a4eaSThomas Richter ctrset_size = cpum_cf_ctrset_size(ctrset, &cpuhw->info); 259a029a4eaSThomas Richter 260a029a4eaSThomas Richter if (ctrset_size) { /* Save data */ 261a029a4eaSThomas Richter need = ctrset_size * sizeof(u64) + sizeof(*ctrdata); 262a029a4eaSThomas Richter if (need <= room) { 263a029a4eaSThomas Richter rc = ctr_stcctm(ctrset, ctrset_size, 264a029a4eaSThomas Richter (u64 *)(ctrdata + 1)); 265a029a4eaSThomas Richter } 266a029a4eaSThomas Richter if (rc != 3 || error_ok) 267a029a4eaSThomas Richter ctrdata->ctr = ctrset_size; 268a029a4eaSThomas Richter else 269a029a4eaSThomas Richter need = 0; 270a029a4eaSThomas Richter } 271a029a4eaSThomas Richter 272a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, 273a029a4eaSThomas Richter "%s ctrset %d ctrset_size %zu cfvn %d csvn %d" 274a029a4eaSThomas Richter " need %zd rc %d\n", __func__, ctrset, ctrset_size, 275a029a4eaSThomas Richter cpuhw->info.cfvn, cpuhw->info.csvn, need, rc); 276a029a4eaSThomas Richter return need; 277a029a4eaSThomas Richter } 278a029a4eaSThomas Richter 2795dddfaacSHeiko Carstens static const u64 cpumf_ctr_ctl[CPUMF_CTR_SET_MAX] = { 2805dddfaacSHeiko Carstens [CPUMF_CTR_SET_BASIC] = 0x02, 2815dddfaacSHeiko Carstens [CPUMF_CTR_SET_USER] = 0x04, 2825dddfaacSHeiko Carstens [CPUMF_CTR_SET_CRYPTO] = 0x08, 2835dddfaacSHeiko Carstens [CPUMF_CTR_SET_EXT] = 0x01, 2845dddfaacSHeiko Carstens [CPUMF_CTR_SET_MT_DIAG] = 0x20, 2855dddfaacSHeiko Carstens }; 2865dddfaacSHeiko Carstens 287a029a4eaSThomas Richter /* Read out all counter sets and save them in the provided data buffer. 288a029a4eaSThomas Richter * The last 64 byte host an artificial trailer entry. 289a029a4eaSThomas Richter */ 290a029a4eaSThomas Richter static size_t cfdiag_getctr(void *data, size_t sz, unsigned long auth, 291a029a4eaSThomas Richter bool error_ok) 292a029a4eaSThomas Richter { 293a029a4eaSThomas Richter struct cf_trailer_entry *trailer; 294a029a4eaSThomas Richter size_t offset = 0, done; 295a029a4eaSThomas Richter int i; 296a029a4eaSThomas Richter 297a029a4eaSThomas Richter memset(data, 0, sz); 298a029a4eaSThomas Richter sz -= sizeof(*trailer); /* Always room for trailer */ 299a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 300a029a4eaSThomas Richter struct cf_ctrset_entry *ctrdata = data + offset; 301a029a4eaSThomas Richter 302a029a4eaSThomas Richter if (!(auth & cpumf_ctr_ctl[i])) 303a029a4eaSThomas Richter continue; /* Counter set not authorized */ 304a029a4eaSThomas Richter 305a029a4eaSThomas Richter done = cfdiag_getctrset(ctrdata, i, sz - offset, error_ok); 306a029a4eaSThomas Richter offset += done; 307a029a4eaSThomas Richter } 308a029a4eaSThomas Richter trailer = data + offset; 309a029a4eaSThomas Richter cfdiag_trailer(trailer); 310a029a4eaSThomas Richter return offset + sizeof(*trailer); 311a029a4eaSThomas Richter } 312a029a4eaSThomas Richter 313a029a4eaSThomas Richter /* Calculate the difference for each counter in a counter set. */ 314a029a4eaSThomas Richter static void cfdiag_diffctrset(u64 *pstart, u64 *pstop, int counters) 315a029a4eaSThomas Richter { 316a029a4eaSThomas Richter for (; --counters >= 0; ++pstart, ++pstop) 317a029a4eaSThomas Richter if (*pstop >= *pstart) 318a029a4eaSThomas Richter *pstop -= *pstart; 319a029a4eaSThomas Richter else 320a029a4eaSThomas Richter *pstop = *pstart - *pstop + 1; 321a029a4eaSThomas Richter } 322a029a4eaSThomas Richter 323a029a4eaSThomas Richter /* Scan the counter sets and calculate the difference of each counter 324a029a4eaSThomas Richter * in each set. The result is the increment of each counter during the 325a029a4eaSThomas Richter * period the counter set has been activated. 326a029a4eaSThomas Richter * 327a029a4eaSThomas Richter * Return true on success. 328a029a4eaSThomas Richter */ 329a029a4eaSThomas Richter static int cfdiag_diffctr(struct cpu_cf_events *cpuhw, unsigned long auth) 330a029a4eaSThomas Richter { 331a029a4eaSThomas Richter struct cf_trailer_entry *trailer_start, *trailer_stop; 332a029a4eaSThomas Richter struct cf_ctrset_entry *ctrstart, *ctrstop; 333a029a4eaSThomas Richter size_t offset = 0; 334a029a4eaSThomas Richter 335a029a4eaSThomas Richter auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1; 336a029a4eaSThomas Richter do { 337a029a4eaSThomas Richter ctrstart = (struct cf_ctrset_entry *)(cpuhw->start + offset); 338a029a4eaSThomas Richter ctrstop = (struct cf_ctrset_entry *)(cpuhw->stop + offset); 339a029a4eaSThomas Richter 340a029a4eaSThomas Richter if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) { 341a029a4eaSThomas Richter pr_err_once("cpum_cf_diag counter set compare error " 342a029a4eaSThomas Richter "in set %i\n", ctrstart->set); 343a029a4eaSThomas Richter return 0; 344a029a4eaSThomas Richter } 345a029a4eaSThomas Richter auth &= ~cpumf_ctr_ctl[ctrstart->set]; 346a029a4eaSThomas Richter if (ctrstart->def == CF_DIAG_CTRSET_DEF) { 347a029a4eaSThomas Richter cfdiag_diffctrset((u64 *)(ctrstart + 1), 348a029a4eaSThomas Richter (u64 *)(ctrstop + 1), ctrstart->ctr); 349a029a4eaSThomas Richter offset += ctrstart->ctr * sizeof(u64) + 350a029a4eaSThomas Richter sizeof(*ctrstart); 351a029a4eaSThomas Richter } 352a029a4eaSThomas Richter } while (ctrstart->def && auth); 353a029a4eaSThomas Richter 354a029a4eaSThomas Richter /* Save time_stamp from start of event in stop's trailer */ 355a029a4eaSThomas Richter trailer_start = (struct cf_trailer_entry *)(cpuhw->start + offset); 356a029a4eaSThomas Richter trailer_stop = (struct cf_trailer_entry *)(cpuhw->stop + offset); 357a029a4eaSThomas Richter trailer_stop->progusage[0] = trailer_start->timestamp; 358a029a4eaSThomas Richter 359a029a4eaSThomas Richter return 1; 360a029a4eaSThomas Richter } 361212188a5SHendrik Brueckner 362ee699f32SHendrik Brueckner static enum cpumf_ctr_set get_counter_set(u64 event) 363212188a5SHendrik Brueckner { 364ee699f32SHendrik Brueckner int set = CPUMF_CTR_SET_MAX; 365212188a5SHendrik Brueckner 366212188a5SHendrik Brueckner if (event < 32) 367212188a5SHendrik Brueckner set = CPUMF_CTR_SET_BASIC; 368212188a5SHendrik Brueckner else if (event < 64) 369212188a5SHendrik Brueckner set = CPUMF_CTR_SET_USER; 370212188a5SHendrik Brueckner else if (event < 128) 371212188a5SHendrik Brueckner set = CPUMF_CTR_SET_CRYPTO; 37246a984ffSThomas Richter else if (event < 288) 373212188a5SHendrik Brueckner set = CPUMF_CTR_SET_EXT; 374ee699f32SHendrik Brueckner else if (event >= 448 && event < 496) 375ee699f32SHendrik Brueckner set = CPUMF_CTR_SET_MT_DIAG; 376212188a5SHendrik Brueckner 377212188a5SHendrik Brueckner return set; 378212188a5SHendrik Brueckner } 379212188a5SHendrik Brueckner 380a029a4eaSThomas Richter static int validate_ctr_version(const struct hw_perf_event *hwc, 381a029a4eaSThomas Richter enum cpumf_ctr_set set) 382212188a5SHendrik Brueckner { 383f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw; 384212188a5SHendrik Brueckner int err = 0; 385ee699f32SHendrik Brueckner u16 mtdiag_ctl; 386212188a5SHendrik Brueckner 387f1c0b831SHendrik Brueckner cpuhw = &get_cpu_var(cpu_cf_events); 388212188a5SHendrik Brueckner 389212188a5SHendrik Brueckner /* check required version for counter sets */ 390a029a4eaSThomas Richter switch (set) { 391212188a5SHendrik Brueckner case CPUMF_CTR_SET_BASIC: 392212188a5SHendrik Brueckner case CPUMF_CTR_SET_USER: 393212188a5SHendrik Brueckner if (cpuhw->info.cfvn < 1) 394212188a5SHendrik Brueckner err = -EOPNOTSUPP; 395212188a5SHendrik Brueckner break; 396212188a5SHendrik Brueckner case CPUMF_CTR_SET_CRYPTO: 39746a984ffSThomas Richter if ((cpuhw->info.csvn >= 1 && cpuhw->info.csvn <= 5 && 39846a984ffSThomas Richter hwc->config > 79) || 39946a984ffSThomas Richter (cpuhw->info.csvn >= 6 && hwc->config > 83)) 40046a984ffSThomas Richter err = -EOPNOTSUPP; 40146a984ffSThomas Richter break; 402212188a5SHendrik Brueckner case CPUMF_CTR_SET_EXT: 403212188a5SHendrik Brueckner if (cpuhw->info.csvn < 1) 404212188a5SHendrik Brueckner err = -EOPNOTSUPP; 405f47586b2SHendrik Brueckner if ((cpuhw->info.csvn == 1 && hwc->config > 159) || 406f47586b2SHendrik Brueckner (cpuhw->info.csvn == 2 && hwc->config > 175) || 40746a984ffSThomas Richter (cpuhw->info.csvn >= 3 && cpuhw->info.csvn <= 5 40846a984ffSThomas Richter && hwc->config > 255) || 40946a984ffSThomas Richter (cpuhw->info.csvn >= 6 && hwc->config > 287)) 410f47586b2SHendrik Brueckner err = -EOPNOTSUPP; 411212188a5SHendrik Brueckner break; 412ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MT_DIAG: 413ee699f32SHendrik Brueckner if (cpuhw->info.csvn <= 3) 414ee699f32SHendrik Brueckner err = -EOPNOTSUPP; 415ee699f32SHendrik Brueckner /* 416ee699f32SHendrik Brueckner * MT-diagnostic counters are read-only. The counter set 417ee699f32SHendrik Brueckner * is automatically enabled and activated on all CPUs with 418ee699f32SHendrik Brueckner * multithreading (SMT). Deactivation of multithreading 419ee699f32SHendrik Brueckner * also disables the counter set. State changes are ignored 420ee699f32SHendrik Brueckner * by lcctl(). Because Linux controls SMT enablement through 421ee699f32SHendrik Brueckner * a kernel parameter only, the counter set is either disabled 422ee699f32SHendrik Brueckner * or enabled and active. 423ee699f32SHendrik Brueckner * 424ee699f32SHendrik Brueckner * Thus, the counters can only be used if SMT is on and the 425ee699f32SHendrik Brueckner * counter set is enabled and active. 426ee699f32SHendrik Brueckner */ 42730e145f8SHendrik Brueckner mtdiag_ctl = cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG]; 428ee699f32SHendrik Brueckner if (!((cpuhw->info.auth_ctl & mtdiag_ctl) && 429ee699f32SHendrik Brueckner (cpuhw->info.enable_ctl & mtdiag_ctl) && 430ee699f32SHendrik Brueckner (cpuhw->info.act_ctl & mtdiag_ctl))) 431ee699f32SHendrik Brueckner err = -EOPNOTSUPP; 432ee699f32SHendrik Brueckner break; 433a029a4eaSThomas Richter case CPUMF_CTR_SET_MAX: 434a029a4eaSThomas Richter err = -EOPNOTSUPP; 435212188a5SHendrik Brueckner } 436212188a5SHendrik Brueckner 437f1c0b831SHendrik Brueckner put_cpu_var(cpu_cf_events); 438212188a5SHendrik Brueckner return err; 439212188a5SHendrik Brueckner } 440212188a5SHendrik Brueckner 441212188a5SHendrik Brueckner static int validate_ctr_auth(const struct hw_perf_event *hwc) 442212188a5SHendrik Brueckner { 443f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw; 444212188a5SHendrik Brueckner int err = 0; 445212188a5SHendrik Brueckner 446f1c0b831SHendrik Brueckner cpuhw = &get_cpu_var(cpu_cf_events); 447212188a5SHendrik Brueckner 44858f8e9daSHendrik Brueckner /* Check authorization for cpu counter sets. 44958f8e9daSHendrik Brueckner * If the particular CPU counter set is not authorized, 45058f8e9daSHendrik Brueckner * return with -ENOENT in order to fall back to other 45158f8e9daSHendrik Brueckner * PMUs that might suffice the event request. 45258f8e9daSHendrik Brueckner */ 453a029a4eaSThomas Richter if (!(hwc->config_base & cpuhw->info.auth_ctl)) 45458f8e9daSHendrik Brueckner err = -ENOENT; 455212188a5SHendrik Brueckner 456f1c0b831SHendrik Brueckner put_cpu_var(cpu_cf_events); 457212188a5SHendrik Brueckner return err; 458212188a5SHendrik Brueckner } 459212188a5SHendrik Brueckner 460212188a5SHendrik Brueckner /* 461212188a5SHendrik Brueckner * Change the CPUMF state to active. 462212188a5SHendrik Brueckner * Enable and activate the CPU-counter sets according 463212188a5SHendrik Brueckner * to the per-cpu control state. 464212188a5SHendrik Brueckner */ 465212188a5SHendrik Brueckner static void cpumf_pmu_enable(struct pmu *pmu) 466212188a5SHendrik Brueckner { 467f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 468212188a5SHendrik Brueckner int err; 469212188a5SHendrik Brueckner 470212188a5SHendrik Brueckner if (cpuhw->flags & PMU_F_ENABLED) 471212188a5SHendrik Brueckner return; 472212188a5SHendrik Brueckner 473a029a4eaSThomas Richter err = lcctl(cpuhw->state | cpuhw->dev_state); 474212188a5SHendrik Brueckner if (err) { 475212188a5SHendrik Brueckner pr_err("Enabling the performance measuring unit " 476af0ee94eSHeiko Carstens "failed with rc=%x\n", err); 477212188a5SHendrik Brueckner return; 478212188a5SHendrik Brueckner } 479212188a5SHendrik Brueckner 480212188a5SHendrik Brueckner cpuhw->flags |= PMU_F_ENABLED; 481212188a5SHendrik Brueckner } 482212188a5SHendrik Brueckner 483212188a5SHendrik Brueckner /* 484212188a5SHendrik Brueckner * Change the CPUMF state to inactive. 485212188a5SHendrik Brueckner * Disable and enable (inactive) the CPU-counter sets according 486212188a5SHendrik Brueckner * to the per-cpu control state. 487212188a5SHendrik Brueckner */ 488212188a5SHendrik Brueckner static void cpumf_pmu_disable(struct pmu *pmu) 489212188a5SHendrik Brueckner { 490f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 491212188a5SHendrik Brueckner int err; 492212188a5SHendrik Brueckner u64 inactive; 493212188a5SHendrik Brueckner 494212188a5SHendrik Brueckner if (!(cpuhw->flags & PMU_F_ENABLED)) 495212188a5SHendrik Brueckner return; 496212188a5SHendrik Brueckner 497212188a5SHendrik Brueckner inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1); 498a029a4eaSThomas Richter inactive |= cpuhw->dev_state; 499212188a5SHendrik Brueckner err = lcctl(inactive); 500212188a5SHendrik Brueckner if (err) { 501212188a5SHendrik Brueckner pr_err("Disabling the performance measuring unit " 502af0ee94eSHeiko Carstens "failed with rc=%x\n", err); 503212188a5SHendrik Brueckner return; 504212188a5SHendrik Brueckner } 505212188a5SHendrik Brueckner 506212188a5SHendrik Brueckner cpuhw->flags &= ~PMU_F_ENABLED; 507212188a5SHendrik Brueckner } 508212188a5SHendrik Brueckner 509*1e99c242SThomas Richter #define PMC_INIT 0 510*1e99c242SThomas Richter #define PMC_RELEASE 1 511*1e99c242SThomas Richter 512*1e99c242SThomas Richter static void cpum_cf_setup_cpu(void *flags) 513*1e99c242SThomas Richter { 514*1e99c242SThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 515*1e99c242SThomas Richter 516*1e99c242SThomas Richter switch (*((int *)flags)) { 517*1e99c242SThomas Richter case PMC_INIT: 518*1e99c242SThomas Richter memset(&cpuhw->info, 0, sizeof(cpuhw->info)); 519*1e99c242SThomas Richter qctri(&cpuhw->info); 520*1e99c242SThomas Richter cpuhw->flags |= PMU_F_RESERVED; 521*1e99c242SThomas Richter break; 522*1e99c242SThomas Richter 523*1e99c242SThomas Richter case PMC_RELEASE: 524*1e99c242SThomas Richter cpuhw->flags &= ~PMU_F_RESERVED; 525*1e99c242SThomas Richter break; 526*1e99c242SThomas Richter } 527*1e99c242SThomas Richter 528*1e99c242SThomas Richter /* Disable CPU counter sets */ 529*1e99c242SThomas Richter lcctl(0); 530*1e99c242SThomas Richter debug_sprintf_event(cf_dbg, 5, "%s flags %#x flags %#x state %#llx\n", 531*1e99c242SThomas Richter __func__, *(int *)flags, cpuhw->flags, 532*1e99c242SThomas Richter cpuhw->state); 533*1e99c242SThomas Richter } 534*1e99c242SThomas Richter 535*1e99c242SThomas Richter /* Initialize the CPU-measurement counter facility */ 536*1e99c242SThomas Richter static int __kernel_cpumcf_begin(void) 537*1e99c242SThomas Richter { 538*1e99c242SThomas Richter int flags = PMC_INIT; 539*1e99c242SThomas Richter 540*1e99c242SThomas Richter on_each_cpu(cpum_cf_setup_cpu, &flags, 1); 541*1e99c242SThomas Richter irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); 542*1e99c242SThomas Richter 543*1e99c242SThomas Richter return 0; 544*1e99c242SThomas Richter } 545*1e99c242SThomas Richter 546*1e99c242SThomas Richter /* Release the CPU-measurement counter facility */ 547*1e99c242SThomas Richter static void __kernel_cpumcf_end(void) 548*1e99c242SThomas Richter { 549*1e99c242SThomas Richter int flags = PMC_RELEASE; 550*1e99c242SThomas Richter 551*1e99c242SThomas Richter on_each_cpu(cpum_cf_setup_cpu, &flags, 1); 552*1e99c242SThomas Richter irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); 553*1e99c242SThomas Richter } 554212188a5SHendrik Brueckner 555212188a5SHendrik Brueckner /* Number of perf events counting hardware events */ 556212188a5SHendrik Brueckner static atomic_t num_events = ATOMIC_INIT(0); 557212188a5SHendrik Brueckner /* Used to avoid races in calling reserve/release_cpumf_hardware */ 558212188a5SHendrik Brueckner static DEFINE_MUTEX(pmc_reserve_mutex); 559212188a5SHendrik Brueckner 560212188a5SHendrik Brueckner /* Release the PMU if event is the last perf event */ 561212188a5SHendrik Brueckner static void hw_perf_event_destroy(struct perf_event *event) 562212188a5SHendrik Brueckner { 563212188a5SHendrik Brueckner mutex_lock(&pmc_reserve_mutex); 564212188a5SHendrik Brueckner if (atomic_dec_return(&num_events) == 0) 5653d33345aSHendrik Brueckner __kernel_cpumcf_end(); 566212188a5SHendrik Brueckner mutex_unlock(&pmc_reserve_mutex); 567212188a5SHendrik Brueckner } 568212188a5SHendrik Brueckner 569212188a5SHendrik Brueckner /* CPUMF <-> perf event mappings for kernel+userspace (basic set) */ 570212188a5SHendrik Brueckner static const int cpumf_generic_events_basic[] = { 571212188a5SHendrik Brueckner [PERF_COUNT_HW_CPU_CYCLES] = 0, 572212188a5SHendrik Brueckner [PERF_COUNT_HW_INSTRUCTIONS] = 1, 573212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_REFERENCES] = -1, 574212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_MISSES] = -1, 575212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1, 576212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_MISSES] = -1, 577212188a5SHendrik Brueckner [PERF_COUNT_HW_BUS_CYCLES] = -1, 578212188a5SHendrik Brueckner }; 579212188a5SHendrik Brueckner /* CPUMF <-> perf event mappings for userspace (problem-state set) */ 580212188a5SHendrik Brueckner static const int cpumf_generic_events_user[] = { 581212188a5SHendrik Brueckner [PERF_COUNT_HW_CPU_CYCLES] = 32, 582212188a5SHendrik Brueckner [PERF_COUNT_HW_INSTRUCTIONS] = 33, 583212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_REFERENCES] = -1, 584212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_MISSES] = -1, 585212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1, 586212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_MISSES] = -1, 587212188a5SHendrik Brueckner [PERF_COUNT_HW_BUS_CYCLES] = -1, 588212188a5SHendrik Brueckner }; 589212188a5SHendrik Brueckner 590a029a4eaSThomas Richter static void cpumf_hw_inuse(void) 591a029a4eaSThomas Richter { 592a029a4eaSThomas Richter mutex_lock(&pmc_reserve_mutex); 593a029a4eaSThomas Richter if (atomic_inc_return(&num_events) == 1) 594a029a4eaSThomas Richter __kernel_cpumcf_begin(); 595a029a4eaSThomas Richter mutex_unlock(&pmc_reserve_mutex); 596a029a4eaSThomas Richter } 597a029a4eaSThomas Richter 59891d5364dSThomas Richter static int is_userspace_event(u64 ev) 59991d5364dSThomas Richter { 60091d5364dSThomas Richter return cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev || 60191d5364dSThomas Richter cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev; 60291d5364dSThomas Richter } 60391d5364dSThomas Richter 6046a82e23fSThomas Richter static int __hw_perf_event_init(struct perf_event *event, unsigned int type) 605212188a5SHendrik Brueckner { 606212188a5SHendrik Brueckner struct perf_event_attr *attr = &event->attr; 607212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 608ee699f32SHendrik Brueckner enum cpumf_ctr_set set; 60947b74785SThomas Richter int err = 0; 610212188a5SHendrik Brueckner u64 ev; 611212188a5SHendrik Brueckner 6126a82e23fSThomas Richter switch (type) { 613212188a5SHendrik Brueckner case PERF_TYPE_RAW: 614212188a5SHendrik Brueckner /* Raw events are used to access counters directly, 615212188a5SHendrik Brueckner * hence do not permit excludes */ 616212188a5SHendrik Brueckner if (attr->exclude_kernel || attr->exclude_user || 617212188a5SHendrik Brueckner attr->exclude_hv) 618212188a5SHendrik Brueckner return -EOPNOTSUPP; 619212188a5SHendrik Brueckner ev = attr->config; 620212188a5SHendrik Brueckner break; 621212188a5SHendrik Brueckner 622212188a5SHendrik Brueckner case PERF_TYPE_HARDWARE: 623613a41b0SThomas Richter if (is_sampling_event(event)) /* No sampling support */ 624613a41b0SThomas Richter return -ENOENT; 625212188a5SHendrik Brueckner ev = attr->config; 626212188a5SHendrik Brueckner if (!attr->exclude_user && attr->exclude_kernel) { 62791d5364dSThomas Richter /* 62891d5364dSThomas Richter * Count user space (problem-state) only 62991d5364dSThomas Richter * Handle events 32 and 33 as 0:u and 1:u 63091d5364dSThomas Richter */ 63191d5364dSThomas Richter if (!is_userspace_event(ev)) { 632212188a5SHendrik Brueckner if (ev >= ARRAY_SIZE(cpumf_generic_events_user)) 633212188a5SHendrik Brueckner return -EOPNOTSUPP; 634212188a5SHendrik Brueckner ev = cpumf_generic_events_user[ev]; 63591d5364dSThomas Richter } 636212188a5SHendrik Brueckner } else if (!attr->exclude_kernel && attr->exclude_user) { 63791d5364dSThomas Richter /* No support for kernel space counters only */ 638212188a5SHendrik Brueckner return -EOPNOTSUPP; 63991d5364dSThomas Richter } else { 64091d5364dSThomas Richter /* Count user and kernel space, incl. events 32 + 33 */ 64191d5364dSThomas Richter if (!is_userspace_event(ev)) { 642212188a5SHendrik Brueckner if (ev >= ARRAY_SIZE(cpumf_generic_events_basic)) 643212188a5SHendrik Brueckner return -EOPNOTSUPP; 644212188a5SHendrik Brueckner ev = cpumf_generic_events_basic[ev]; 645212188a5SHendrik Brueckner } 64691d5364dSThomas Richter } 647212188a5SHendrik Brueckner break; 648212188a5SHendrik Brueckner 649212188a5SHendrik Brueckner default: 650212188a5SHendrik Brueckner return -ENOENT; 651212188a5SHendrik Brueckner } 652212188a5SHendrik Brueckner 653212188a5SHendrik Brueckner if (ev == -1) 654212188a5SHendrik Brueckner return -ENOENT; 655212188a5SHendrik Brueckner 65620ba46daSHendrik Brueckner if (ev > PERF_CPUM_CF_MAX_CTR) 6570bb2ae1bSThomas Richter return -ENOENT; 658212188a5SHendrik Brueckner 659ee699f32SHendrik Brueckner /* Obtain the counter set to which the specified counter belongs */ 660ee699f32SHendrik Brueckner set = get_counter_set(ev); 661ee699f32SHendrik Brueckner switch (set) { 662ee699f32SHendrik Brueckner case CPUMF_CTR_SET_BASIC: 663ee699f32SHendrik Brueckner case CPUMF_CTR_SET_USER: 664ee699f32SHendrik Brueckner case CPUMF_CTR_SET_CRYPTO: 665ee699f32SHendrik Brueckner case CPUMF_CTR_SET_EXT: 666ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MT_DIAG: 667ee699f32SHendrik Brueckner /* 668ee699f32SHendrik Brueckner * Use the hardware perf event structure to store the 669ee699f32SHendrik Brueckner * counter number in the 'config' member and the counter 670a029a4eaSThomas Richter * set number in the 'config_base' as bit mask. 671a029a4eaSThomas Richter * It is later used to enable/disable the counter(s). 672212188a5SHendrik Brueckner */ 673212188a5SHendrik Brueckner hwc->config = ev; 674a029a4eaSThomas Richter hwc->config_base = cpumf_ctr_ctl[set]; 675ee699f32SHendrik Brueckner break; 676ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MAX: 677ee699f32SHendrik Brueckner /* The counter could not be associated to a counter set */ 678ee699f32SHendrik Brueckner return -EINVAL; 6791c0a9c79SJiapeng Chong } 680212188a5SHendrik Brueckner 681212188a5SHendrik Brueckner /* Initialize for using the CPU-measurement counter facility */ 682a029a4eaSThomas Richter cpumf_hw_inuse(); 683212188a5SHendrik Brueckner event->destroy = hw_perf_event_destroy; 684212188a5SHendrik Brueckner 685212188a5SHendrik Brueckner /* Finally, validate version and authorization of the counter set */ 686212188a5SHendrik Brueckner err = validate_ctr_auth(hwc); 687212188a5SHendrik Brueckner if (!err) 688a029a4eaSThomas Richter err = validate_ctr_version(hwc, set); 689212188a5SHendrik Brueckner 690212188a5SHendrik Brueckner return err; 691212188a5SHendrik Brueckner } 692212188a5SHendrik Brueckner 693be857b7fSThomas Richter /* Events CPU_CYLCES and INSTRUCTIONS can be submitted with two different 694be857b7fSThomas Richter * attribute::type values: 695be857b7fSThomas Richter * - PERF_TYPE_HARDWARE: 696be857b7fSThomas Richter * - pmu->type: 697be857b7fSThomas Richter * Handle both type of invocations identical. They address the same hardware. 698be857b7fSThomas Richter * The result is different when event modifiers exclude_kernel and/or 699be857b7fSThomas Richter * exclude_user are also set. 700be857b7fSThomas Richter */ 701be857b7fSThomas Richter static int cpumf_pmu_event_type(struct perf_event *event) 702be857b7fSThomas Richter { 703be857b7fSThomas Richter u64 ev = event->attr.config; 704be857b7fSThomas Richter 705be857b7fSThomas Richter if (cpumf_generic_events_basic[PERF_COUNT_HW_CPU_CYCLES] == ev || 706be857b7fSThomas Richter cpumf_generic_events_basic[PERF_COUNT_HW_INSTRUCTIONS] == ev || 707be857b7fSThomas Richter cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev || 708be857b7fSThomas Richter cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev) 709be857b7fSThomas Richter return PERF_TYPE_HARDWARE; 710be857b7fSThomas Richter return PERF_TYPE_RAW; 711be857b7fSThomas Richter } 712be857b7fSThomas Richter 713212188a5SHendrik Brueckner static int cpumf_pmu_event_init(struct perf_event *event) 714212188a5SHendrik Brueckner { 7156a82e23fSThomas Richter unsigned int type = event->attr.type; 716212188a5SHendrik Brueckner int err; 717212188a5SHendrik Brueckner 7186a82e23fSThomas Richter if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) 7196a82e23fSThomas Richter err = __hw_perf_event_init(event, type); 7206a82e23fSThomas Richter else if (event->pmu->type == type) 7216a82e23fSThomas Richter /* Registered as unknown PMU */ 722be857b7fSThomas Richter err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); 7236a82e23fSThomas Richter else 724212188a5SHendrik Brueckner return -ENOENT; 725212188a5SHendrik Brueckner 726212188a5SHendrik Brueckner if (unlikely(err) && event->destroy) 727212188a5SHendrik Brueckner event->destroy(event); 728212188a5SHendrik Brueckner 729212188a5SHendrik Brueckner return err; 730212188a5SHendrik Brueckner } 731212188a5SHendrik Brueckner 732212188a5SHendrik Brueckner static int hw_perf_event_reset(struct perf_event *event) 733212188a5SHendrik Brueckner { 734212188a5SHendrik Brueckner u64 prev, new; 735212188a5SHendrik Brueckner int err; 736212188a5SHendrik Brueckner 737212188a5SHendrik Brueckner do { 738212188a5SHendrik Brueckner prev = local64_read(&event->hw.prev_count); 739212188a5SHendrik Brueckner err = ecctr(event->hw.config, &new); 740212188a5SHendrik Brueckner if (err) { 741212188a5SHendrik Brueckner if (err != 3) 742212188a5SHendrik Brueckner break; 743212188a5SHendrik Brueckner /* The counter is not (yet) available. This 744212188a5SHendrik Brueckner * might happen if the counter set to which 745212188a5SHendrik Brueckner * this counter belongs is in the disabled 746212188a5SHendrik Brueckner * state. 747212188a5SHendrik Brueckner */ 748212188a5SHendrik Brueckner new = 0; 749212188a5SHendrik Brueckner } 750212188a5SHendrik Brueckner } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev); 751212188a5SHendrik Brueckner 752212188a5SHendrik Brueckner return err; 753212188a5SHendrik Brueckner } 754212188a5SHendrik Brueckner 755485527baSHendrik Brueckner static void hw_perf_event_update(struct perf_event *event) 756212188a5SHendrik Brueckner { 757212188a5SHendrik Brueckner u64 prev, new, delta; 758212188a5SHendrik Brueckner int err; 759212188a5SHendrik Brueckner 760212188a5SHendrik Brueckner do { 761212188a5SHendrik Brueckner prev = local64_read(&event->hw.prev_count); 762212188a5SHendrik Brueckner err = ecctr(event->hw.config, &new); 763212188a5SHendrik Brueckner if (err) 764485527baSHendrik Brueckner return; 765212188a5SHendrik Brueckner } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev); 766212188a5SHendrik Brueckner 767212188a5SHendrik Brueckner delta = (prev <= new) ? new - prev 768212188a5SHendrik Brueckner : (-1ULL - prev) + new + 1; /* overflow */ 769212188a5SHendrik Brueckner local64_add(delta, &event->count); 770212188a5SHendrik Brueckner } 771212188a5SHendrik Brueckner 772212188a5SHendrik Brueckner static void cpumf_pmu_read(struct perf_event *event) 773212188a5SHendrik Brueckner { 774212188a5SHendrik Brueckner if (event->hw.state & PERF_HES_STOPPED) 775212188a5SHendrik Brueckner return; 776212188a5SHendrik Brueckner 777212188a5SHendrik Brueckner hw_perf_event_update(event); 778212188a5SHendrik Brueckner } 779212188a5SHendrik Brueckner 780212188a5SHendrik Brueckner static void cpumf_pmu_start(struct perf_event *event, int flags) 781212188a5SHendrik Brueckner { 782f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 783212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 784a029a4eaSThomas Richter int i; 785212188a5SHendrik Brueckner 78615e5b53fSThomas Richter if (!(hwc->state & PERF_HES_STOPPED)) 787212188a5SHendrik Brueckner return; 788212188a5SHendrik Brueckner 789212188a5SHendrik Brueckner hwc->state = 0; 790212188a5SHendrik Brueckner 791212188a5SHendrik Brueckner /* (Re-)enable and activate the counter set */ 792212188a5SHendrik Brueckner ctr_set_enable(&cpuhw->state, hwc->config_base); 793212188a5SHendrik Brueckner ctr_set_start(&cpuhw->state, hwc->config_base); 794212188a5SHendrik Brueckner 795212188a5SHendrik Brueckner /* The counter set to which this counter belongs can be already active. 796212188a5SHendrik Brueckner * Because all counters in a set are active, the event->hw.prev_count 797212188a5SHendrik Brueckner * needs to be synchronized. At this point, the counter set can be in 798212188a5SHendrik Brueckner * the inactive or disabled state. 799212188a5SHendrik Brueckner */ 800a029a4eaSThomas Richter if (hwc->config == PERF_EVENT_CPUM_CF_DIAG) { 801a029a4eaSThomas Richter cpuhw->usedss = cfdiag_getctr(cpuhw->start, 802a029a4eaSThomas Richter sizeof(cpuhw->start), 803a029a4eaSThomas Richter hwc->config_base, true); 804a029a4eaSThomas Richter } else { 805212188a5SHendrik Brueckner hw_perf_event_reset(event); 806a029a4eaSThomas Richter } 807212188a5SHendrik Brueckner 808a029a4eaSThomas Richter /* Increment refcount for counter sets */ 809a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) 810a029a4eaSThomas Richter if ((hwc->config_base & cpumf_ctr_ctl[i])) 811a029a4eaSThomas Richter atomic_inc(&cpuhw->ctr_set[i]); 812a029a4eaSThomas Richter } 813a029a4eaSThomas Richter 814a029a4eaSThomas Richter /* Create perf event sample with the counter sets as raw data. The sample 815a029a4eaSThomas Richter * is then pushed to the event subsystem and the function checks for 816a029a4eaSThomas Richter * possible event overflows. If an event overflow occurs, the PMU is 817a029a4eaSThomas Richter * stopped. 818a029a4eaSThomas Richter * 819a029a4eaSThomas Richter * Return non-zero if an event overflow occurred. 820a029a4eaSThomas Richter */ 821a029a4eaSThomas Richter static int cfdiag_push_sample(struct perf_event *event, 822a029a4eaSThomas Richter struct cpu_cf_events *cpuhw) 823a029a4eaSThomas Richter { 824a029a4eaSThomas Richter struct perf_sample_data data; 825a029a4eaSThomas Richter struct perf_raw_record raw; 826a029a4eaSThomas Richter struct pt_regs regs; 827a029a4eaSThomas Richter int overflow; 828a029a4eaSThomas Richter 829a029a4eaSThomas Richter /* Setup perf sample */ 830a029a4eaSThomas Richter perf_sample_data_init(&data, 0, event->hw.last_period); 831a029a4eaSThomas Richter memset(®s, 0, sizeof(regs)); 832a029a4eaSThomas Richter memset(&raw, 0, sizeof(raw)); 833a029a4eaSThomas Richter 834a029a4eaSThomas Richter if (event->attr.sample_type & PERF_SAMPLE_CPU) 835a029a4eaSThomas Richter data.cpu_entry.cpu = event->cpu; 836a029a4eaSThomas Richter if (event->attr.sample_type & PERF_SAMPLE_RAW) { 837a029a4eaSThomas Richter raw.frag.size = cpuhw->usedss; 838a029a4eaSThomas Richter raw.frag.data = cpuhw->stop; 839a029a4eaSThomas Richter raw.size = raw.frag.size; 840a029a4eaSThomas Richter data.raw = &raw; 841838d9bb6SNamhyung Kim data.sample_flags |= PERF_SAMPLE_RAW; 842a029a4eaSThomas Richter } 843a029a4eaSThomas Richter 844a029a4eaSThomas Richter overflow = perf_event_overflow(event, &data, ®s); 845a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, 846a029a4eaSThomas Richter "%s event %#llx sample_type %#llx raw %d ov %d\n", 847a029a4eaSThomas Richter __func__, event->hw.config, 848a029a4eaSThomas Richter event->attr.sample_type, raw.size, overflow); 849a029a4eaSThomas Richter if (overflow) 850a029a4eaSThomas Richter event->pmu->stop(event, 0); 851a029a4eaSThomas Richter 852a029a4eaSThomas Richter perf_event_update_userpage(event); 853a029a4eaSThomas Richter return overflow; 854212188a5SHendrik Brueckner } 855212188a5SHendrik Brueckner 856212188a5SHendrik Brueckner static void cpumf_pmu_stop(struct perf_event *event, int flags) 857212188a5SHendrik Brueckner { 858f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 859212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 860a029a4eaSThomas Richter int i; 861212188a5SHendrik Brueckner 862212188a5SHendrik Brueckner if (!(hwc->state & PERF_HES_STOPPED)) { 863212188a5SHendrik Brueckner /* Decrement reference count for this counter set and if this 864212188a5SHendrik Brueckner * is the last used counter in the set, clear activation 865212188a5SHendrik Brueckner * control and set the counter set state to inactive. 866212188a5SHendrik Brueckner */ 867a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 868a029a4eaSThomas Richter if (!(hwc->config_base & cpumf_ctr_ctl[i])) 869a029a4eaSThomas Richter continue; 870a029a4eaSThomas Richter if (!atomic_dec_return(&cpuhw->ctr_set[i])) 871a029a4eaSThomas Richter ctr_set_stop(&cpuhw->state, cpumf_ctr_ctl[i]); 872a029a4eaSThomas Richter } 8730cceeab5SThomas Richter hwc->state |= PERF_HES_STOPPED; 874212188a5SHendrik Brueckner } 875212188a5SHendrik Brueckner 876212188a5SHendrik Brueckner if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { 877a029a4eaSThomas Richter if (hwc->config == PERF_EVENT_CPUM_CF_DIAG) { 878a029a4eaSThomas Richter local64_inc(&event->count); 879a029a4eaSThomas Richter cpuhw->usedss = cfdiag_getctr(cpuhw->stop, 880a029a4eaSThomas Richter sizeof(cpuhw->stop), 881a029a4eaSThomas Richter event->hw.config_base, 882a029a4eaSThomas Richter false); 883a029a4eaSThomas Richter if (cfdiag_diffctr(cpuhw, event->hw.config_base)) 884a029a4eaSThomas Richter cfdiag_push_sample(event, cpuhw); 8859d48c7afSThomas Richter } else if (cpuhw->flags & PMU_F_RESERVED) { 8869d48c7afSThomas Richter /* Only update when PMU not hotplugged off */ 887212188a5SHendrik Brueckner hw_perf_event_update(event); 8889d48c7afSThomas Richter } 8890cceeab5SThomas Richter hwc->state |= PERF_HES_UPTODATE; 890212188a5SHendrik Brueckner } 891212188a5SHendrik Brueckner } 892212188a5SHendrik Brueckner 893212188a5SHendrik Brueckner static int cpumf_pmu_add(struct perf_event *event, int flags) 894212188a5SHendrik Brueckner { 895f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 896212188a5SHendrik Brueckner 897212188a5SHendrik Brueckner ctr_set_enable(&cpuhw->state, event->hw.config_base); 898212188a5SHendrik Brueckner event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 899212188a5SHendrik Brueckner 900212188a5SHendrik Brueckner if (flags & PERF_EF_START) 901212188a5SHendrik Brueckner cpumf_pmu_start(event, PERF_EF_RELOAD); 902212188a5SHendrik Brueckner 903212188a5SHendrik Brueckner return 0; 904212188a5SHendrik Brueckner } 905212188a5SHendrik Brueckner 906212188a5SHendrik Brueckner static void cpumf_pmu_del(struct perf_event *event, int flags) 907212188a5SHendrik Brueckner { 908f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 909a029a4eaSThomas Richter int i; 910212188a5SHendrik Brueckner 911212188a5SHendrik Brueckner cpumf_pmu_stop(event, PERF_EF_UPDATE); 912212188a5SHendrik Brueckner 913212188a5SHendrik Brueckner /* Check if any counter in the counter set is still used. If not used, 914212188a5SHendrik Brueckner * change the counter set to the disabled state. This also clears the 915212188a5SHendrik Brueckner * content of all counters in the set. 916212188a5SHendrik Brueckner * 917212188a5SHendrik Brueckner * When a new perf event has been added but not yet started, this can 918212188a5SHendrik Brueckner * clear enable control and resets all counters in a set. Therefore, 919212188a5SHendrik Brueckner * cpumf_pmu_start() always has to reenable a counter set. 920212188a5SHendrik Brueckner */ 921a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) 922a029a4eaSThomas Richter if (!atomic_read(&cpuhw->ctr_set[i])) 923a029a4eaSThomas Richter ctr_set_disable(&cpuhw->state, cpumf_ctr_ctl[i]); 924212188a5SHendrik Brueckner } 925212188a5SHendrik Brueckner 926212188a5SHendrik Brueckner /* Performance monitoring unit for s390x */ 927212188a5SHendrik Brueckner static struct pmu cpumf_pmu = { 9289254e70cSHendrik Brueckner .task_ctx_nr = perf_sw_context, 9299254e70cSHendrik Brueckner .capabilities = PERF_PMU_CAP_NO_INTERRUPT, 930212188a5SHendrik Brueckner .pmu_enable = cpumf_pmu_enable, 931212188a5SHendrik Brueckner .pmu_disable = cpumf_pmu_disable, 932212188a5SHendrik Brueckner .event_init = cpumf_pmu_event_init, 933212188a5SHendrik Brueckner .add = cpumf_pmu_add, 934212188a5SHendrik Brueckner .del = cpumf_pmu_del, 935212188a5SHendrik Brueckner .start = cpumf_pmu_start, 936212188a5SHendrik Brueckner .stop = cpumf_pmu_stop, 937212188a5SHendrik Brueckner .read = cpumf_pmu_read, 938212188a5SHendrik Brueckner }; 939212188a5SHendrik Brueckner 940*1e99c242SThomas Richter static int cpum_cf_setup(unsigned int cpu, int flags) 941*1e99c242SThomas Richter { 942*1e99c242SThomas Richter local_irq_disable(); 943*1e99c242SThomas Richter cpum_cf_setup_cpu(&flags); 944*1e99c242SThomas Richter local_irq_enable(); 945*1e99c242SThomas Richter return 0; 946*1e99c242SThomas Richter } 947*1e99c242SThomas Richter 948*1e99c242SThomas Richter static int cfset_online_cpu(unsigned int cpu); 949*1e99c242SThomas Richter static int cpum_cf_online_cpu(unsigned int cpu) 950*1e99c242SThomas Richter { 951*1e99c242SThomas Richter debug_sprintf_event(cf_dbg, 4, "%s cpu %d in_irq %ld\n", __func__, 952*1e99c242SThomas Richter cpu, in_interrupt()); 953*1e99c242SThomas Richter cpum_cf_setup(cpu, PMC_INIT); 954*1e99c242SThomas Richter return cfset_online_cpu(cpu); 955*1e99c242SThomas Richter } 956*1e99c242SThomas Richter 957*1e99c242SThomas Richter static int cfset_offline_cpu(unsigned int cpu); 958*1e99c242SThomas Richter static int cpum_cf_offline_cpu(unsigned int cpu) 959*1e99c242SThomas Richter { 960*1e99c242SThomas Richter debug_sprintf_event(cf_dbg, 4, "%s cpu %d\n", __func__, cpu); 961*1e99c242SThomas Richter cfset_offline_cpu(cpu); 962*1e99c242SThomas Richter return cpum_cf_setup(cpu, PMC_RELEASE); 963*1e99c242SThomas Richter } 964*1e99c242SThomas Richter 9657a8f09acSThomas Richter /* Return true if store counter set multiple instruction is available */ 9667a8f09acSThomas Richter static inline int stccm_avail(void) 9677a8f09acSThomas Richter { 9687a8f09acSThomas Richter return test_facility(142); 9697a8f09acSThomas Richter } 9707a8f09acSThomas Richter 971*1e99c242SThomas Richter /* CPU-measurement alerts for the counter facility */ 972*1e99c242SThomas Richter static void cpumf_measurement_alert(struct ext_code ext_code, 973*1e99c242SThomas Richter unsigned int alert, unsigned long unused) 974*1e99c242SThomas Richter { 975*1e99c242SThomas Richter struct cpu_cf_events *cpuhw; 976*1e99c242SThomas Richter 977*1e99c242SThomas Richter if (!(alert & CPU_MF_INT_CF_MASK)) 978*1e99c242SThomas Richter return; 979*1e99c242SThomas Richter 980*1e99c242SThomas Richter inc_irq_stat(IRQEXT_CMC); 981*1e99c242SThomas Richter cpuhw = this_cpu_ptr(&cpu_cf_events); 982*1e99c242SThomas Richter 983*1e99c242SThomas Richter /* 984*1e99c242SThomas Richter * Measurement alerts are shared and might happen when the PMU 985*1e99c242SThomas Richter * is not reserved. Ignore these alerts in this case. 986*1e99c242SThomas Richter */ 987*1e99c242SThomas Richter if (!(cpuhw->flags & PMU_F_RESERVED)) 988*1e99c242SThomas Richter return; 989*1e99c242SThomas Richter 990*1e99c242SThomas Richter /* counter authorization change alert */ 991*1e99c242SThomas Richter if (alert & CPU_MF_INT_CF_CACA) 992*1e99c242SThomas Richter qctri(&cpuhw->info); 993*1e99c242SThomas Richter 994*1e99c242SThomas Richter /* loss of counter data alert */ 995*1e99c242SThomas Richter if (alert & CPU_MF_INT_CF_LCDA) 996*1e99c242SThomas Richter pr_err("CPU[%i] Counter data was lost\n", smp_processor_id()); 997*1e99c242SThomas Richter 998*1e99c242SThomas Richter /* loss of MT counter data alert */ 999*1e99c242SThomas Richter if (alert & CPU_MF_INT_CF_MTDA) 1000*1e99c242SThomas Richter pr_warn("CPU[%i] MT counter data was lost\n", 1001*1e99c242SThomas Richter smp_processor_id()); 1002*1e99c242SThomas Richter } 1003*1e99c242SThomas Richter 1004a029a4eaSThomas Richter static int cfset_init(void); 1005212188a5SHendrik Brueckner static int __init cpumf_pmu_init(void) 1006212188a5SHendrik Brueckner { 1007212188a5SHendrik Brueckner int rc; 1008212188a5SHendrik Brueckner 1009ea53e699SThomas Richter if (!cpum_cf_avail()) 1010212188a5SHendrik Brueckner return -ENODEV; 1011212188a5SHendrik Brueckner 1012*1e99c242SThomas Richter /* 1013*1e99c242SThomas Richter * Clear bit 15 of cr0 to unauthorize problem-state to 1014*1e99c242SThomas Richter * extract measurement counters 1015*1e99c242SThomas Richter */ 1016*1e99c242SThomas Richter ctl_clear_bit(0, 48); 1017*1e99c242SThomas Richter 1018*1e99c242SThomas Richter /* register handler for measurement-alert interruptions */ 1019*1e99c242SThomas Richter rc = register_external_irq(EXT_IRQ_MEASURE_ALERT, 1020*1e99c242SThomas Richter cpumf_measurement_alert); 1021*1e99c242SThomas Richter if (rc) { 1022*1e99c242SThomas Richter pr_err("Registering for CPU-measurement alerts failed with rc=%i\n", rc); 1023*1e99c242SThomas Richter return rc; 1024*1e99c242SThomas Richter } 1025*1e99c242SThomas Richter 1026a029a4eaSThomas Richter /* Setup s390dbf facility */ 1027a029a4eaSThomas Richter cf_dbg = debug_register(KMSG_COMPONENT, 2, 1, 128); 1028a029a4eaSThomas Richter if (!cf_dbg) { 1029a029a4eaSThomas Richter pr_err("Registration of s390dbf(cpum_cf) failed\n"); 1030*1e99c242SThomas Richter rc = -ENOMEM; 1031*1e99c242SThomas Richter goto out1; 10327d244643Skernel test robot } 1033a029a4eaSThomas Richter debug_register_view(cf_dbg, &debug_sprintf_view); 1034a029a4eaSThomas Richter 1035c7168325SHendrik Brueckner cpumf_pmu.attr_groups = cpumf_cf_event_group(); 10366a82e23fSThomas Richter rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", -1); 1037a029a4eaSThomas Richter if (rc) { 1038212188a5SHendrik Brueckner pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); 1039*1e99c242SThomas Richter goto out2; 1040a029a4eaSThomas Richter } else if (stccm_avail()) { /* Setup counter set device */ 1041a029a4eaSThomas Richter cfset_init(); 1042a029a4eaSThomas Richter } 1043*1e99c242SThomas Richter 1044*1e99c242SThomas Richter rc = cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE, 1045*1e99c242SThomas Richter "perf/s390/cf:online", 1046*1e99c242SThomas Richter cpum_cf_online_cpu, cpum_cf_offline_cpu); 1047*1e99c242SThomas Richter return rc; 1048*1e99c242SThomas Richter 1049*1e99c242SThomas Richter out2: 1050*1e99c242SThomas Richter debug_unregister_view(cf_dbg, &debug_sprintf_view); 1051*1e99c242SThomas Richter debug_unregister(cf_dbg); 1052*1e99c242SThomas Richter out1: 1053*1e99c242SThomas Richter unregister_external_irq(EXT_IRQ_MEASURE_ALERT, cpumf_measurement_alert); 1054212188a5SHendrik Brueckner return rc; 1055212188a5SHendrik Brueckner } 1056a029a4eaSThomas Richter 1057a029a4eaSThomas Richter /* Support for the CPU Measurement Facility counter set extraction using 1058a029a4eaSThomas Richter * device /dev/hwctr. This allows user space programs to extract complete 1059a029a4eaSThomas Richter * counter set via normal file operations. 1060a029a4eaSThomas Richter */ 1061a029a4eaSThomas Richter 106245338031SThomas Richter static atomic_t cfset_opencnt = ATOMIC_INIT(0); /* Access count */ 1063a029a4eaSThomas Richter static DEFINE_MUTEX(cfset_ctrset_mutex);/* Synchronize access to hardware */ 1064a029a4eaSThomas Richter struct cfset_call_on_cpu_parm { /* Parm struct for smp_call_on_cpu */ 1065a029a4eaSThomas Richter unsigned int sets; /* Counter set bit mask */ 1066a029a4eaSThomas Richter atomic_t cpus_ack; /* # CPUs successfully executed func */ 1067a029a4eaSThomas Richter }; 1068a029a4eaSThomas Richter 106945338031SThomas Richter static struct cfset_session { /* CPUs and counter set bit mask */ 107045338031SThomas Richter struct list_head head; /* Head of list of active processes */ 107145338031SThomas Richter } cfset_session = { 107245338031SThomas Richter .head = LIST_HEAD_INIT(cfset_session.head) 107345338031SThomas Richter }; 107445338031SThomas Richter 107545338031SThomas Richter struct cfset_request { /* CPUs and counter set bit mask */ 1076a029a4eaSThomas Richter unsigned long ctrset; /* Bit mask of counter set to read */ 1077a029a4eaSThomas Richter cpumask_t mask; /* CPU mask to read from */ 107845338031SThomas Richter struct list_head node; /* Chain to cfset_session.head */ 107945338031SThomas Richter }; 1080a029a4eaSThomas Richter 108145338031SThomas Richter static void cfset_session_init(void) 1082a029a4eaSThomas Richter { 108345338031SThomas Richter INIT_LIST_HEAD(&cfset_session.head); 108445338031SThomas Richter } 108545338031SThomas Richter 108645338031SThomas Richter /* Remove current request from global bookkeeping. Maintain a counter set bit 108745338031SThomas Richter * mask on a per CPU basis. 108845338031SThomas Richter * Done in process context under mutex protection. 108945338031SThomas Richter */ 109045338031SThomas Richter static void cfset_session_del(struct cfset_request *p) 109145338031SThomas Richter { 109245338031SThomas Richter list_del(&p->node); 109345338031SThomas Richter } 109445338031SThomas Richter 109545338031SThomas Richter /* Add current request to global bookkeeping. Maintain a counter set bit mask 109645338031SThomas Richter * on a per CPU basis. 109745338031SThomas Richter * Done in process context under mutex protection. 109845338031SThomas Richter */ 109945338031SThomas Richter static void cfset_session_add(struct cfset_request *p) 110045338031SThomas Richter { 110145338031SThomas Richter list_add(&p->node, &cfset_session.head); 1102a029a4eaSThomas Richter } 1103a029a4eaSThomas Richter 1104a029a4eaSThomas Richter /* The /dev/hwctr device access uses PMU_F_IN_USE to mark the device access 1105a029a4eaSThomas Richter * path is currently used. 1106a029a4eaSThomas Richter * The cpu_cf_events::dev_state is used to denote counter sets in use by this 1107a029a4eaSThomas Richter * interface. It is always or'ed in. If this interface is not active, its 1108a029a4eaSThomas Richter * value is zero and no additional counter sets will be included. 1109a029a4eaSThomas Richter * 1110a029a4eaSThomas Richter * The cpu_cf_events::state is used by the perf_event_open SVC and remains 1111a029a4eaSThomas Richter * unchanged. 1112a029a4eaSThomas Richter * 1113a029a4eaSThomas Richter * perf_pmu_enable() and perf_pmu_enable() and its call backs 1114a029a4eaSThomas Richter * cpumf_pmu_enable() and cpumf_pmu_disable() are called by the 1115a029a4eaSThomas Richter * performance measurement subsystem to enable per process 1116a029a4eaSThomas Richter * CPU Measurement counter facility. 1117a029a4eaSThomas Richter * The XXX_enable() and XXX_disable functions are used to turn off 1118a029a4eaSThomas Richter * x86 performance monitoring interrupt (PMI) during scheduling. 1119a029a4eaSThomas Richter * s390 uses these calls to temporarily stop and resume the active CPU 1120a029a4eaSThomas Richter * counters sets during scheduling. 1121a029a4eaSThomas Richter * 1122a029a4eaSThomas Richter * We do allow concurrent access of perf_event_open() SVC and /dev/hwctr 1123a029a4eaSThomas Richter * device access. The perf_event_open() SVC interface makes a lot of effort 1124a029a4eaSThomas Richter * to only run the counters while the calling process is actively scheduled 1125a029a4eaSThomas Richter * to run. 1126a029a4eaSThomas Richter * When /dev/hwctr interface is also used at the same time, the counter sets 1127a029a4eaSThomas Richter * will keep running, even when the process is scheduled off a CPU. 1128a029a4eaSThomas Richter * However this is not a problem and does not lead to wrong counter values 1129a029a4eaSThomas Richter * for the perf_event_open() SVC. The current counter value will be recorded 1130a029a4eaSThomas Richter * during schedule-in. At schedule-out time the current counter value is 1131a029a4eaSThomas Richter * extracted again and the delta is calculated and added to the event. 1132a029a4eaSThomas Richter */ 1133a029a4eaSThomas Richter /* Stop all counter sets via ioctl interface */ 1134a029a4eaSThomas Richter static void cfset_ioctl_off(void *parm) 1135a029a4eaSThomas Richter { 1136a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 1137a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 1138a029a4eaSThomas Richter int rc; 1139a029a4eaSThomas Richter 114045338031SThomas Richter /* Check if any counter set used by /dev/hwc */ 1141a029a4eaSThomas Richter for (rc = CPUMF_CTR_SET_BASIC; rc < CPUMF_CTR_SET_MAX; ++rc) 114245338031SThomas Richter if ((p->sets & cpumf_ctr_ctl[rc])) { 114345338031SThomas Richter if (!atomic_dec_return(&cpuhw->ctr_set[rc])) { 114445338031SThomas Richter ctr_set_disable(&cpuhw->dev_state, 114545338031SThomas Richter cpumf_ctr_ctl[rc]); 114645338031SThomas Richter ctr_set_stop(&cpuhw->dev_state, 114745338031SThomas Richter cpumf_ctr_ctl[rc]); 114845338031SThomas Richter } 114945338031SThomas Richter } 115045338031SThomas Richter /* Keep perf_event_open counter sets */ 115145338031SThomas Richter rc = lcctl(cpuhw->dev_state | cpuhw->state); 1152a029a4eaSThomas Richter if (rc) 1153a029a4eaSThomas Richter pr_err("Counter set stop %#llx of /dev/%s failed rc=%i\n", 1154a029a4eaSThomas Richter cpuhw->state, S390_HWCTR_DEVICE, rc); 115545338031SThomas Richter if (!cpuhw->dev_state) 1156a029a4eaSThomas Richter cpuhw->flags &= ~PMU_F_IN_USE; 1157a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s rc %d state %#llx dev_state %#llx\n", 1158a029a4eaSThomas Richter __func__, rc, cpuhw->state, cpuhw->dev_state); 1159a029a4eaSThomas Richter } 1160a029a4eaSThomas Richter 1161a029a4eaSThomas Richter /* Start counter sets on particular CPU */ 1162a029a4eaSThomas Richter static void cfset_ioctl_on(void *parm) 1163a029a4eaSThomas Richter { 1164a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 1165a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 1166a029a4eaSThomas Richter int rc; 1167a029a4eaSThomas Richter 1168a029a4eaSThomas Richter cpuhw->flags |= PMU_F_IN_USE; 1169a029a4eaSThomas Richter ctr_set_enable(&cpuhw->dev_state, p->sets); 1170a029a4eaSThomas Richter ctr_set_start(&cpuhw->dev_state, p->sets); 1171a029a4eaSThomas Richter for (rc = CPUMF_CTR_SET_BASIC; rc < CPUMF_CTR_SET_MAX; ++rc) 1172a029a4eaSThomas Richter if ((p->sets & cpumf_ctr_ctl[rc])) 1173a029a4eaSThomas Richter atomic_inc(&cpuhw->ctr_set[rc]); 1174a029a4eaSThomas Richter rc = lcctl(cpuhw->dev_state | cpuhw->state); /* Start counter sets */ 1175a029a4eaSThomas Richter if (!rc) 1176a029a4eaSThomas Richter atomic_inc(&p->cpus_ack); 1177a029a4eaSThomas Richter else 1178a029a4eaSThomas Richter pr_err("Counter set start %#llx of /dev/%s failed rc=%i\n", 1179a029a4eaSThomas Richter cpuhw->dev_state | cpuhw->state, S390_HWCTR_DEVICE, rc); 1180a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s rc %d state %#llx dev_state %#llx\n", 1181a029a4eaSThomas Richter __func__, rc, cpuhw->state, cpuhw->dev_state); 1182a029a4eaSThomas Richter } 1183a029a4eaSThomas Richter 1184a029a4eaSThomas Richter static void cfset_release_cpu(void *p) 1185a029a4eaSThomas Richter { 1186a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 1187a029a4eaSThomas Richter int rc; 1188a029a4eaSThomas Richter 1189a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s state %#llx dev_state %#llx\n", 1190a029a4eaSThomas Richter __func__, cpuhw->state, cpuhw->dev_state); 119145338031SThomas Richter cpuhw->dev_state = 0; 1192a029a4eaSThomas Richter rc = lcctl(cpuhw->state); /* Keep perf_event_open counter sets */ 1193a029a4eaSThomas Richter if (rc) 1194a029a4eaSThomas Richter pr_err("Counter set release %#llx of /dev/%s failed rc=%i\n", 1195a029a4eaSThomas Richter cpuhw->state, S390_HWCTR_DEVICE, rc); 119645338031SThomas Richter } 119745338031SThomas Richter 119845338031SThomas Richter /* This modifies the process CPU mask to adopt it to the currently online 119945338031SThomas Richter * CPUs. Offline CPUs can not be addresses. This call terminates the access 120045338031SThomas Richter * and is usually followed by close() or a new iotcl(..., START, ...) which 120145338031SThomas Richter * creates a new request structure. 120245338031SThomas Richter */ 120345338031SThomas Richter static void cfset_all_stop(struct cfset_request *req) 120445338031SThomas Richter { 120545338031SThomas Richter struct cfset_call_on_cpu_parm p = { 120645338031SThomas Richter .sets = req->ctrset, 120745338031SThomas Richter }; 120845338031SThomas Richter 120945338031SThomas Richter cpumask_and(&req->mask, &req->mask, cpu_online_mask); 121045338031SThomas Richter on_each_cpu_mask(&req->mask, cfset_ioctl_off, &p, 1); 1211a029a4eaSThomas Richter } 1212a029a4eaSThomas Richter 1213a029a4eaSThomas Richter /* Release function is also called when application gets terminated without 1214a029a4eaSThomas Richter * doing a proper ioctl(..., S390_HWCTR_STOP, ...) command. 1215a029a4eaSThomas Richter */ 1216a029a4eaSThomas Richter static int cfset_release(struct inode *inode, struct file *file) 1217a029a4eaSThomas Richter { 121845338031SThomas Richter mutex_lock(&cfset_ctrset_mutex); 121945338031SThomas Richter /* Open followed by close/exit has no private_data */ 122045338031SThomas Richter if (file->private_data) { 122145338031SThomas Richter cfset_all_stop(file->private_data); 122245338031SThomas Richter cfset_session_del(file->private_data); 122345338031SThomas Richter kfree(file->private_data); 122445338031SThomas Richter file->private_data = NULL; 122545338031SThomas Richter } 122645338031SThomas Richter if (!atomic_dec_return(&cfset_opencnt)) 1227a029a4eaSThomas Richter on_each_cpu(cfset_release_cpu, NULL, 1); 122845338031SThomas Richter mutex_unlock(&cfset_ctrset_mutex); 122945338031SThomas Richter 1230a029a4eaSThomas Richter hw_perf_event_destroy(NULL); 1231a029a4eaSThomas Richter return 0; 1232a029a4eaSThomas Richter } 1233a029a4eaSThomas Richter 1234a029a4eaSThomas Richter static int cfset_open(struct inode *inode, struct file *file) 1235a029a4eaSThomas Richter { 1236a029a4eaSThomas Richter if (!capable(CAP_SYS_ADMIN)) 1237a029a4eaSThomas Richter return -EPERM; 123845338031SThomas Richter mutex_lock(&cfset_ctrset_mutex); 123945338031SThomas Richter if (atomic_inc_return(&cfset_opencnt) == 1) 124045338031SThomas Richter cfset_session_init(); 124145338031SThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1242a029a4eaSThomas Richter 1243a029a4eaSThomas Richter cpumf_hw_inuse(); 1244a029a4eaSThomas Richter file->private_data = NULL; 1245a029a4eaSThomas Richter /* nonseekable_open() never fails */ 1246a029a4eaSThomas Richter return nonseekable_open(inode, file); 1247a029a4eaSThomas Richter } 1248a029a4eaSThomas Richter 124945338031SThomas Richter static int cfset_all_start(struct cfset_request *req) 1250a029a4eaSThomas Richter { 1251a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p = { 125245338031SThomas Richter .sets = req->ctrset, 1253a029a4eaSThomas Richter .cpus_ack = ATOMIC_INIT(0), 1254a029a4eaSThomas Richter }; 1255a029a4eaSThomas Richter cpumask_var_t mask; 1256a029a4eaSThomas Richter int rc = 0; 1257a029a4eaSThomas Richter 1258a029a4eaSThomas Richter if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 1259a029a4eaSThomas Richter return -ENOMEM; 126045338031SThomas Richter cpumask_and(mask, &req->mask, cpu_online_mask); 1261a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_ioctl_on, &p, 1); 1262a029a4eaSThomas Richter if (atomic_read(&p.cpus_ack) != cpumask_weight(mask)) { 1263a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_ioctl_off, &p, 1); 1264a029a4eaSThomas Richter rc = -EIO; 1265a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s CPUs missing", __func__); 1266a029a4eaSThomas Richter } 1267a029a4eaSThomas Richter free_cpumask_var(mask); 1268a029a4eaSThomas Richter return rc; 1269a029a4eaSThomas Richter } 1270a029a4eaSThomas Richter 1271a029a4eaSThomas Richter /* Return the maximum required space for all possible CPUs in case one 1272a029a4eaSThomas Richter * CPU will be onlined during the START, READ, STOP cycles. 1273a029a4eaSThomas Richter * To find out the size of the counter sets, any one CPU will do. They 1274a029a4eaSThomas Richter * all have the same counter sets. 1275a029a4eaSThomas Richter */ 1276a029a4eaSThomas Richter static size_t cfset_needspace(unsigned int sets) 1277a029a4eaSThomas Richter { 1278a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = get_cpu_ptr(&cpu_cf_events); 1279a029a4eaSThomas Richter size_t bytes = 0; 1280a029a4eaSThomas Richter int i; 1281a029a4eaSThomas Richter 1282a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 1283a029a4eaSThomas Richter if (!(sets & cpumf_ctr_ctl[i])) 1284a029a4eaSThomas Richter continue; 1285a029a4eaSThomas Richter bytes += cpum_cf_ctrset_size(i, &cpuhw->info) * sizeof(u64) + 1286a029a4eaSThomas Richter sizeof(((struct s390_ctrset_setdata *)0)->set) + 1287a029a4eaSThomas Richter sizeof(((struct s390_ctrset_setdata *)0)->no_cnts); 1288a029a4eaSThomas Richter } 1289a029a4eaSThomas Richter bytes = sizeof(((struct s390_ctrset_read *)0)->no_cpus) + nr_cpu_ids * 1290a029a4eaSThomas Richter (bytes + sizeof(((struct s390_ctrset_cpudata *)0)->cpu_nr) + 1291a029a4eaSThomas Richter sizeof(((struct s390_ctrset_cpudata *)0)->no_sets)); 1292a029a4eaSThomas Richter put_cpu_ptr(&cpu_cf_events); 1293a029a4eaSThomas Richter return bytes; 1294a029a4eaSThomas Richter } 1295a029a4eaSThomas Richter 1296a029a4eaSThomas Richter static int cfset_all_copy(unsigned long arg, cpumask_t *mask) 1297a029a4eaSThomas Richter { 1298a029a4eaSThomas Richter struct s390_ctrset_read __user *ctrset_read; 1299a029a4eaSThomas Richter unsigned int cpu, cpus, rc; 1300a029a4eaSThomas Richter void __user *uptr; 1301a029a4eaSThomas Richter 1302a029a4eaSThomas Richter ctrset_read = (struct s390_ctrset_read __user *)arg; 1303a029a4eaSThomas Richter uptr = ctrset_read->data; 1304a029a4eaSThomas Richter for_each_cpu(cpu, mask) { 1305a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = per_cpu_ptr(&cpu_cf_events, cpu); 1306a029a4eaSThomas Richter struct s390_ctrset_cpudata __user *ctrset_cpudata; 1307a029a4eaSThomas Richter 1308a029a4eaSThomas Richter ctrset_cpudata = uptr; 1309a029a4eaSThomas Richter rc = put_user(cpu, &ctrset_cpudata->cpu_nr); 1310a029a4eaSThomas Richter rc |= put_user(cpuhw->sets, &ctrset_cpudata->no_sets); 1311a029a4eaSThomas Richter rc |= copy_to_user(ctrset_cpudata->data, cpuhw->data, 1312a029a4eaSThomas Richter cpuhw->used); 1313a029a4eaSThomas Richter if (rc) 1314a029a4eaSThomas Richter return -EFAULT; 1315a029a4eaSThomas Richter uptr += sizeof(struct s390_ctrset_cpudata) + cpuhw->used; 1316a029a4eaSThomas Richter cond_resched(); 1317a029a4eaSThomas Richter } 1318a029a4eaSThomas Richter cpus = cpumask_weight(mask); 1319a029a4eaSThomas Richter if (put_user(cpus, &ctrset_read->no_cpus)) 1320a029a4eaSThomas Richter return -EFAULT; 1321a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s copied %ld\n", __func__, 1322a029a4eaSThomas Richter uptr - (void __user *)ctrset_read->data); 1323a029a4eaSThomas Richter return 0; 1324a029a4eaSThomas Richter } 1325a029a4eaSThomas Richter 1326a029a4eaSThomas Richter static size_t cfset_cpuset_read(struct s390_ctrset_setdata *p, int ctrset, 1327a029a4eaSThomas Richter int ctrset_size, size_t room) 1328a029a4eaSThomas Richter { 1329a029a4eaSThomas Richter size_t need = 0; 1330a029a4eaSThomas Richter int rc = -1; 1331a029a4eaSThomas Richter 1332a029a4eaSThomas Richter need = sizeof(*p) + sizeof(u64) * ctrset_size; 1333a029a4eaSThomas Richter if (need <= room) { 1334a029a4eaSThomas Richter p->set = cpumf_ctr_ctl[ctrset]; 1335a029a4eaSThomas Richter p->no_cnts = ctrset_size; 1336a029a4eaSThomas Richter rc = ctr_stcctm(ctrset, ctrset_size, (u64 *)p->cv); 1337a029a4eaSThomas Richter if (rc == 3) /* Nothing stored */ 1338a029a4eaSThomas Richter need = 0; 1339a029a4eaSThomas Richter } 1340a029a4eaSThomas Richter return need; 1341a029a4eaSThomas Richter } 1342a029a4eaSThomas Richter 1343a029a4eaSThomas Richter /* Read all counter sets. */ 1344a029a4eaSThomas Richter static void cfset_cpu_read(void *parm) 1345a029a4eaSThomas Richter { 1346a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 1347a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 1348a029a4eaSThomas Richter int set, set_size; 1349a029a4eaSThomas Richter size_t space; 1350a029a4eaSThomas Richter 1351a029a4eaSThomas Richter /* No data saved yet */ 1352a029a4eaSThomas Richter cpuhw->used = 0; 1353a029a4eaSThomas Richter cpuhw->sets = 0; 1354a029a4eaSThomas Richter memset(cpuhw->data, 0, sizeof(cpuhw->data)); 1355a029a4eaSThomas Richter 1356a029a4eaSThomas Richter /* Scan the counter sets */ 1357a029a4eaSThomas Richter for (set = CPUMF_CTR_SET_BASIC; set < CPUMF_CTR_SET_MAX; ++set) { 1358a029a4eaSThomas Richter struct s390_ctrset_setdata *sp = (void *)cpuhw->data + 1359a029a4eaSThomas Richter cpuhw->used; 1360a029a4eaSThomas Richter 1361a029a4eaSThomas Richter if (!(p->sets & cpumf_ctr_ctl[set])) 1362a029a4eaSThomas Richter continue; /* Counter set not in list */ 1363a029a4eaSThomas Richter set_size = cpum_cf_ctrset_size(set, &cpuhw->info); 1364a029a4eaSThomas Richter space = sizeof(cpuhw->data) - cpuhw->used; 1365a029a4eaSThomas Richter space = cfset_cpuset_read(sp, set, set_size, space); 1366a029a4eaSThomas Richter if (space) { 1367a029a4eaSThomas Richter cpuhw->used += space; 1368a029a4eaSThomas Richter cpuhw->sets += 1; 1369a029a4eaSThomas Richter } 1370a029a4eaSThomas Richter } 1371a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s sets %d used %zd\n", __func__, 1372a029a4eaSThomas Richter cpuhw->sets, cpuhw->used); 1373a029a4eaSThomas Richter } 1374a029a4eaSThomas Richter 137545338031SThomas Richter static int cfset_all_read(unsigned long arg, struct cfset_request *req) 1376a029a4eaSThomas Richter { 1377a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 1378a029a4eaSThomas Richter cpumask_var_t mask; 1379a029a4eaSThomas Richter int rc; 1380a029a4eaSThomas Richter 1381a029a4eaSThomas Richter if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 1382a029a4eaSThomas Richter return -ENOMEM; 1383a029a4eaSThomas Richter 138445338031SThomas Richter p.sets = req->ctrset; 138545338031SThomas Richter cpumask_and(mask, &req->mask, cpu_online_mask); 1386a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_cpu_read, &p, 1); 1387a029a4eaSThomas Richter rc = cfset_all_copy(arg, mask); 1388a029a4eaSThomas Richter free_cpumask_var(mask); 1389a029a4eaSThomas Richter return rc; 1390a029a4eaSThomas Richter } 1391a029a4eaSThomas Richter 139245338031SThomas Richter static long cfset_ioctl_read(unsigned long arg, struct cfset_request *req) 1393a029a4eaSThomas Richter { 1394a029a4eaSThomas Richter struct s390_ctrset_read read; 139545338031SThomas Richter int ret = -ENODATA; 1396a029a4eaSThomas Richter 139745338031SThomas Richter if (req && req->ctrset) { 1398a029a4eaSThomas Richter if (copy_from_user(&read, (char __user *)arg, sizeof(read))) 1399a029a4eaSThomas Richter return -EFAULT; 140045338031SThomas Richter ret = cfset_all_read(arg, req); 140145338031SThomas Richter } 1402a029a4eaSThomas Richter return ret; 1403a029a4eaSThomas Richter } 1404a029a4eaSThomas Richter 140545338031SThomas Richter static long cfset_ioctl_stop(struct file *file) 1406a029a4eaSThomas Richter { 140745338031SThomas Richter struct cfset_request *req = file->private_data; 140845338031SThomas Richter int ret = -ENXIO; 1409a029a4eaSThomas Richter 141045338031SThomas Richter if (req) { 141145338031SThomas Richter cfset_all_stop(req); 141245338031SThomas Richter cfset_session_del(req); 141345338031SThomas Richter kfree(req); 141445338031SThomas Richter file->private_data = NULL; 141545338031SThomas Richter ret = 0; 1416a029a4eaSThomas Richter } 1417a029a4eaSThomas Richter return ret; 1418a029a4eaSThomas Richter } 1419a029a4eaSThomas Richter 142045338031SThomas Richter static long cfset_ioctl_start(unsigned long arg, struct file *file) 1421a029a4eaSThomas Richter { 1422a029a4eaSThomas Richter struct s390_ctrset_start __user *ustart; 1423a029a4eaSThomas Richter struct s390_ctrset_start start; 142445338031SThomas Richter struct cfset_request *preq; 1425a029a4eaSThomas Richter void __user *umask; 1426a029a4eaSThomas Richter unsigned int len; 1427a029a4eaSThomas Richter int ret = 0; 1428a029a4eaSThomas Richter size_t need; 1429a029a4eaSThomas Richter 143045338031SThomas Richter if (file->private_data) 1431a029a4eaSThomas Richter return -EBUSY; 1432a029a4eaSThomas Richter ustart = (struct s390_ctrset_start __user *)arg; 1433a029a4eaSThomas Richter if (copy_from_user(&start, ustart, sizeof(start))) 1434a029a4eaSThomas Richter return -EFAULT; 1435a029a4eaSThomas Richter if (start.version != S390_HWCTR_START_VERSION) 1436a029a4eaSThomas Richter return -EINVAL; 1437a029a4eaSThomas Richter if (start.counter_sets & ~(cpumf_ctr_ctl[CPUMF_CTR_SET_BASIC] | 1438a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_USER] | 1439a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_CRYPTO] | 1440a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_EXT] | 1441a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG])) 1442a029a4eaSThomas Richter return -EINVAL; /* Invalid counter set */ 1443a029a4eaSThomas Richter if (!start.counter_sets) 1444a029a4eaSThomas Richter return -EINVAL; /* No counter set at all? */ 144545338031SThomas Richter 144645338031SThomas Richter preq = kzalloc(sizeof(*preq), GFP_KERNEL); 144745338031SThomas Richter if (!preq) 144845338031SThomas Richter return -ENOMEM; 144945338031SThomas Richter cpumask_clear(&preq->mask); 1450a029a4eaSThomas Richter len = min_t(u64, start.cpumask_len, cpumask_size()); 1451a029a4eaSThomas Richter umask = (void __user *)start.cpumask; 145245338031SThomas Richter if (copy_from_user(&preq->mask, umask, len)) { 145345338031SThomas Richter kfree(preq); 1454a029a4eaSThomas Richter return -EFAULT; 145545338031SThomas Richter } 145645338031SThomas Richter if (cpumask_empty(&preq->mask)) { 145745338031SThomas Richter kfree(preq); 1458a029a4eaSThomas Richter return -EINVAL; 145945338031SThomas Richter } 1460a029a4eaSThomas Richter need = cfset_needspace(start.counter_sets); 146145338031SThomas Richter if (put_user(need, &ustart->data_bytes)) { 146245338031SThomas Richter kfree(preq); 146345338031SThomas Richter return -EFAULT; 146445338031SThomas Richter } 146545338031SThomas Richter preq->ctrset = start.counter_sets; 146645338031SThomas Richter ret = cfset_all_start(preq); 146745338031SThomas Richter if (!ret) { 146845338031SThomas Richter cfset_session_add(preq); 146945338031SThomas Richter file->private_data = preq; 147045338031SThomas Richter debug_sprintf_event(cf_dbg, 4, "%s set %#lx need %ld ret %d\n", 147145338031SThomas Richter __func__, preq->ctrset, need, ret); 147245338031SThomas Richter } else { 147345338031SThomas Richter kfree(preq); 147445338031SThomas Richter } 1475a029a4eaSThomas Richter return ret; 1476a029a4eaSThomas Richter } 1477a029a4eaSThomas Richter 1478a029a4eaSThomas Richter /* Entry point to the /dev/hwctr device interface. 1479a029a4eaSThomas Richter * The ioctl system call supports three subcommands: 1480a029a4eaSThomas Richter * S390_HWCTR_START: Start the specified counter sets on a CPU list. The 1481a029a4eaSThomas Richter * counter set keeps running until explicitly stopped. Returns the number 1482a029a4eaSThomas Richter * of bytes needed to store the counter values. If another S390_HWCTR_START 1483a029a4eaSThomas Richter * ioctl subcommand is called without a previous S390_HWCTR_STOP stop 148445338031SThomas Richter * command on the same file descriptor, -EBUSY is returned. 1485a029a4eaSThomas Richter * S390_HWCTR_READ: Read the counter set values from specified CPU list given 1486a029a4eaSThomas Richter * with the S390_HWCTR_START command. 1487a029a4eaSThomas Richter * S390_HWCTR_STOP: Stops the counter sets on the CPU list given with the 1488a029a4eaSThomas Richter * previous S390_HWCTR_START subcommand. 1489a029a4eaSThomas Richter */ 1490a029a4eaSThomas Richter static long cfset_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1491a029a4eaSThomas Richter { 1492a029a4eaSThomas Richter int ret; 1493a029a4eaSThomas Richter 1494a73de293SSebastian Andrzej Siewior cpus_read_lock(); 1495a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 1496a029a4eaSThomas Richter switch (cmd) { 1497a029a4eaSThomas Richter case S390_HWCTR_START: 149845338031SThomas Richter ret = cfset_ioctl_start(arg, file); 1499a029a4eaSThomas Richter break; 1500a029a4eaSThomas Richter case S390_HWCTR_STOP: 150145338031SThomas Richter ret = cfset_ioctl_stop(file); 1502a029a4eaSThomas Richter break; 1503a029a4eaSThomas Richter case S390_HWCTR_READ: 150445338031SThomas Richter ret = cfset_ioctl_read(arg, file->private_data); 1505a029a4eaSThomas Richter break; 1506a029a4eaSThomas Richter default: 1507a029a4eaSThomas Richter ret = -ENOTTY; 1508a029a4eaSThomas Richter break; 1509a029a4eaSThomas Richter } 1510a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1511a73de293SSebastian Andrzej Siewior cpus_read_unlock(); 1512a029a4eaSThomas Richter return ret; 1513a029a4eaSThomas Richter } 1514a029a4eaSThomas Richter 1515a029a4eaSThomas Richter static const struct file_operations cfset_fops = { 1516a029a4eaSThomas Richter .owner = THIS_MODULE, 1517a029a4eaSThomas Richter .open = cfset_open, 1518a029a4eaSThomas Richter .release = cfset_release, 1519a029a4eaSThomas Richter .unlocked_ioctl = cfset_ioctl, 1520a029a4eaSThomas Richter .compat_ioctl = cfset_ioctl, 1521a029a4eaSThomas Richter .llseek = no_llseek 1522a029a4eaSThomas Richter }; 1523a029a4eaSThomas Richter 1524a029a4eaSThomas Richter static struct miscdevice cfset_dev = { 1525a029a4eaSThomas Richter .name = S390_HWCTR_DEVICE, 1526a029a4eaSThomas Richter .minor = MISC_DYNAMIC_MINOR, 1527a029a4eaSThomas Richter .fops = &cfset_fops, 1528a029a4eaSThomas Richter }; 1529a029a4eaSThomas Richter 153045338031SThomas Richter /* Hotplug add of a CPU. Scan through all active processes and add 153145338031SThomas Richter * that CPU to the list of CPUs supplied with ioctl(..., START, ...). 153245338031SThomas Richter */ 1533*1e99c242SThomas Richter static int cfset_online_cpu(unsigned int cpu) 1534a029a4eaSThomas Richter { 1535a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 153645338031SThomas Richter struct cfset_request *rp; 1537a029a4eaSThomas Richter 1538a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 153945338031SThomas Richter if (!list_empty(&cfset_session.head)) { 154045338031SThomas Richter list_for_each_entry(rp, &cfset_session.head, node) { 154145338031SThomas Richter p.sets = rp->ctrset; 1542a029a4eaSThomas Richter cfset_ioctl_on(&p); 154345338031SThomas Richter cpumask_set_cpu(cpu, &rp->mask); 154445338031SThomas Richter } 1545a029a4eaSThomas Richter } 1546a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1547a029a4eaSThomas Richter return 0; 1548a029a4eaSThomas Richter } 1549a029a4eaSThomas Richter 155045338031SThomas Richter /* Hotplug remove of a CPU. Scan through all active processes and clear 155145338031SThomas Richter * that CPU from the list of CPUs supplied with ioctl(..., START, ...). 155245338031SThomas Richter */ 1553*1e99c242SThomas Richter static int cfset_offline_cpu(unsigned int cpu) 1554a029a4eaSThomas Richter { 1555a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 155645338031SThomas Richter struct cfset_request *rp; 1557a029a4eaSThomas Richter 1558a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 155945338031SThomas Richter if (!list_empty(&cfset_session.head)) { 156045338031SThomas Richter list_for_each_entry(rp, &cfset_session.head, node) { 156145338031SThomas Richter p.sets = rp->ctrset; 1562a029a4eaSThomas Richter cfset_ioctl_off(&p); 156345338031SThomas Richter cpumask_clear_cpu(cpu, &rp->mask); 156445338031SThomas Richter } 1565a029a4eaSThomas Richter } 1566a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1567a029a4eaSThomas Richter return 0; 1568a029a4eaSThomas Richter } 1569a029a4eaSThomas Richter 1570a029a4eaSThomas Richter static void cfdiag_read(struct perf_event *event) 1571a029a4eaSThomas Richter { 1572a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, "%s event %#llx count %ld\n", __func__, 1573a029a4eaSThomas Richter event->attr.config, local64_read(&event->count)); 1574a029a4eaSThomas Richter } 1575a029a4eaSThomas Richter 1576a029a4eaSThomas Richter static int get_authctrsets(void) 1577a029a4eaSThomas Richter { 1578a029a4eaSThomas Richter struct cpu_cf_events *cpuhw; 1579a029a4eaSThomas Richter unsigned long auth = 0; 1580a029a4eaSThomas Richter enum cpumf_ctr_set i; 1581a029a4eaSThomas Richter 1582a029a4eaSThomas Richter cpuhw = &get_cpu_var(cpu_cf_events); 1583a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 1584a029a4eaSThomas Richter if (cpuhw->info.auth_ctl & cpumf_ctr_ctl[i]) 1585a029a4eaSThomas Richter auth |= cpumf_ctr_ctl[i]; 1586a029a4eaSThomas Richter } 1587a029a4eaSThomas Richter put_cpu_var(cpu_cf_events); 1588a029a4eaSThomas Richter return auth; 1589a029a4eaSThomas Richter } 1590a029a4eaSThomas Richter 1591a029a4eaSThomas Richter /* Setup the event. Test for authorized counter sets and only include counter 1592a029a4eaSThomas Richter * sets which are authorized at the time of the setup. Including unauthorized 1593a029a4eaSThomas Richter * counter sets result in specification exception (and panic). 1594a029a4eaSThomas Richter */ 1595a029a4eaSThomas Richter static int cfdiag_event_init2(struct perf_event *event) 1596a029a4eaSThomas Richter { 1597a029a4eaSThomas Richter struct perf_event_attr *attr = &event->attr; 1598a029a4eaSThomas Richter int err = 0; 1599a029a4eaSThomas Richter 1600a029a4eaSThomas Richter /* Set sample_period to indicate sampling */ 1601a029a4eaSThomas Richter event->hw.config = attr->config; 1602a029a4eaSThomas Richter event->hw.sample_period = attr->sample_period; 1603a029a4eaSThomas Richter local64_set(&event->hw.period_left, event->hw.sample_period); 1604a029a4eaSThomas Richter local64_set(&event->count, 0); 1605a029a4eaSThomas Richter event->hw.last_period = event->hw.sample_period; 1606a029a4eaSThomas Richter 1607a029a4eaSThomas Richter /* Add all authorized counter sets to config_base. The 1608a029a4eaSThomas Richter * the hardware init function is either called per-cpu or just once 1609a029a4eaSThomas Richter * for all CPUS (event->cpu == -1). This depends on the whether 1610a029a4eaSThomas Richter * counting is started for all CPUs or on a per workload base where 1611a029a4eaSThomas Richter * the perf event moves from one CPU to another CPU. 1612a029a4eaSThomas Richter * Checking the authorization on any CPU is fine as the hardware 1613a029a4eaSThomas Richter * applies the same authorization settings to all CPUs. 1614a029a4eaSThomas Richter */ 1615a029a4eaSThomas Richter event->hw.config_base = get_authctrsets(); 1616a029a4eaSThomas Richter 1617a029a4eaSThomas Richter /* No authorized counter sets, nothing to count/sample */ 1618a029a4eaSThomas Richter if (!event->hw.config_base) 1619a029a4eaSThomas Richter err = -EINVAL; 1620a029a4eaSThomas Richter 1621a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 5, "%s err %d config_base %#lx\n", 1622a029a4eaSThomas Richter __func__, err, event->hw.config_base); 1623a029a4eaSThomas Richter return err; 1624a029a4eaSThomas Richter } 1625a029a4eaSThomas Richter 1626a029a4eaSThomas Richter static int cfdiag_event_init(struct perf_event *event) 1627a029a4eaSThomas Richter { 1628a029a4eaSThomas Richter struct perf_event_attr *attr = &event->attr; 1629a029a4eaSThomas Richter int err = -ENOENT; 1630a029a4eaSThomas Richter 1631a029a4eaSThomas Richter if (event->attr.config != PERF_EVENT_CPUM_CF_DIAG || 1632a029a4eaSThomas Richter event->attr.type != event->pmu->type) 1633a029a4eaSThomas Richter goto out; 1634a029a4eaSThomas Richter 1635a029a4eaSThomas Richter /* Raw events are used to access counters directly, 1636a029a4eaSThomas Richter * hence do not permit excludes. 1637a029a4eaSThomas Richter * This event is useless without PERF_SAMPLE_RAW to return counter set 1638a029a4eaSThomas Richter * values as raw data. 1639a029a4eaSThomas Richter */ 1640a029a4eaSThomas Richter if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv || 1641a029a4eaSThomas Richter !(attr->sample_type & (PERF_SAMPLE_CPU | PERF_SAMPLE_RAW))) { 1642a029a4eaSThomas Richter err = -EOPNOTSUPP; 1643a029a4eaSThomas Richter goto out; 1644a029a4eaSThomas Richter } 1645a029a4eaSThomas Richter 1646a029a4eaSThomas Richter /* Initialize for using the CPU-measurement counter facility */ 1647a029a4eaSThomas Richter cpumf_hw_inuse(); 1648a029a4eaSThomas Richter event->destroy = hw_perf_event_destroy; 1649a029a4eaSThomas Richter 1650a029a4eaSThomas Richter err = cfdiag_event_init2(event); 1651a029a4eaSThomas Richter if (unlikely(err)) 1652a029a4eaSThomas Richter event->destroy(event); 1653a029a4eaSThomas Richter out: 1654a029a4eaSThomas Richter return err; 1655a029a4eaSThomas Richter } 1656a029a4eaSThomas Richter 1657a029a4eaSThomas Richter /* Create cf_diag/events/CF_DIAG event sysfs file. This counter is used 1658a029a4eaSThomas Richter * to collect the complete counter sets for a scheduled process. Target 1659a029a4eaSThomas Richter * are complete counter sets attached as raw data to the artificial event. 1660a029a4eaSThomas Richter * This results in complete counter sets available when a process is 1661a029a4eaSThomas Richter * scheduled. Contains the delta of every counter while the process was 1662a029a4eaSThomas Richter * running. 1663a029a4eaSThomas Richter */ 1664a029a4eaSThomas Richter CPUMF_EVENT_ATTR(CF_DIAG, CF_DIAG, PERF_EVENT_CPUM_CF_DIAG); 1665a029a4eaSThomas Richter 1666a029a4eaSThomas Richter static struct attribute *cfdiag_events_attr[] = { 1667a029a4eaSThomas Richter CPUMF_EVENT_PTR(CF_DIAG, CF_DIAG), 1668a029a4eaSThomas Richter NULL, 1669a029a4eaSThomas Richter }; 1670a029a4eaSThomas Richter 1671a029a4eaSThomas Richter PMU_FORMAT_ATTR(event, "config:0-63"); 1672a029a4eaSThomas Richter 1673a029a4eaSThomas Richter static struct attribute *cfdiag_format_attr[] = { 1674a029a4eaSThomas Richter &format_attr_event.attr, 1675a029a4eaSThomas Richter NULL, 1676a029a4eaSThomas Richter }; 1677a029a4eaSThomas Richter 1678a029a4eaSThomas Richter static struct attribute_group cfdiag_events_group = { 1679a029a4eaSThomas Richter .name = "events", 1680a029a4eaSThomas Richter .attrs = cfdiag_events_attr, 1681a029a4eaSThomas Richter }; 1682a029a4eaSThomas Richter static struct attribute_group cfdiag_format_group = { 1683a029a4eaSThomas Richter .name = "format", 1684a029a4eaSThomas Richter .attrs = cfdiag_format_attr, 1685a029a4eaSThomas Richter }; 1686a029a4eaSThomas Richter static const struct attribute_group *cfdiag_attr_groups[] = { 1687a029a4eaSThomas Richter &cfdiag_events_group, 1688a029a4eaSThomas Richter &cfdiag_format_group, 1689a029a4eaSThomas Richter NULL, 1690a029a4eaSThomas Richter }; 1691a029a4eaSThomas Richter 1692a029a4eaSThomas Richter /* Performance monitoring unit for event CF_DIAG. Since this event 1693a029a4eaSThomas Richter * is also started and stopped via the perf_event_open() system call, use 1694a029a4eaSThomas Richter * the same event enable/disable call back functions. They do not 1695a029a4eaSThomas Richter * have a pointer to the perf_event strcture as first parameter. 1696a029a4eaSThomas Richter * 1697a029a4eaSThomas Richter * The functions XXX_add, XXX_del, XXX_start and XXX_stop are also common. 1698a029a4eaSThomas Richter * Reuse them and distinguish the event (always first parameter) via 1699a029a4eaSThomas Richter * 'config' member. 1700a029a4eaSThomas Richter */ 1701a029a4eaSThomas Richter static struct pmu cf_diag = { 1702a029a4eaSThomas Richter .task_ctx_nr = perf_sw_context, 1703a029a4eaSThomas Richter .event_init = cfdiag_event_init, 1704a029a4eaSThomas Richter .pmu_enable = cpumf_pmu_enable, 1705a029a4eaSThomas Richter .pmu_disable = cpumf_pmu_disable, 1706a029a4eaSThomas Richter .add = cpumf_pmu_add, 1707a029a4eaSThomas Richter .del = cpumf_pmu_del, 1708a029a4eaSThomas Richter .start = cpumf_pmu_start, 1709a029a4eaSThomas Richter .stop = cpumf_pmu_stop, 1710a029a4eaSThomas Richter .read = cfdiag_read, 1711a029a4eaSThomas Richter 1712a029a4eaSThomas Richter .attr_groups = cfdiag_attr_groups 1713a029a4eaSThomas Richter }; 1714a029a4eaSThomas Richter 1715a029a4eaSThomas Richter /* Calculate memory needed to store all counter sets together with header and 1716a029a4eaSThomas Richter * trailer data. This is independent of the counter set authorization which 1717a029a4eaSThomas Richter * can vary depending on the configuration. 1718a029a4eaSThomas Richter */ 1719a029a4eaSThomas Richter static size_t cfdiag_maxsize(struct cpumf_ctr_info *info) 1720a029a4eaSThomas Richter { 1721a029a4eaSThomas Richter size_t max_size = sizeof(struct cf_trailer_entry); 1722a029a4eaSThomas Richter enum cpumf_ctr_set i; 1723a029a4eaSThomas Richter 1724a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 1725a029a4eaSThomas Richter size_t size = cpum_cf_ctrset_size(i, info); 1726a029a4eaSThomas Richter 1727a029a4eaSThomas Richter if (size) 1728a029a4eaSThomas Richter max_size += size * sizeof(u64) + 1729a029a4eaSThomas Richter sizeof(struct cf_ctrset_entry); 1730a029a4eaSThomas Richter } 1731a029a4eaSThomas Richter return max_size; 1732a029a4eaSThomas Richter } 1733a029a4eaSThomas Richter 1734a029a4eaSThomas Richter /* Get the CPU speed, try sampling facility first and CPU attributes second. */ 1735a029a4eaSThomas Richter static void cfdiag_get_cpu_speed(void) 1736a029a4eaSThomas Richter { 17374efd417fSVasily Gorbik unsigned long mhz; 17384efd417fSVasily Gorbik 1739a029a4eaSThomas Richter if (cpum_sf_avail()) { /* Sampling facility first */ 1740a029a4eaSThomas Richter struct hws_qsi_info_block si; 1741a029a4eaSThomas Richter 1742a029a4eaSThomas Richter memset(&si, 0, sizeof(si)); 1743a029a4eaSThomas Richter if (!qsi(&si)) { 1744a029a4eaSThomas Richter cfdiag_cpu_speed = si.cpu_speed; 1745a029a4eaSThomas Richter return; 1746a029a4eaSThomas Richter } 1747a029a4eaSThomas Richter } 1748a029a4eaSThomas Richter 1749a029a4eaSThomas Richter /* Fallback: CPU speed extract static part. Used in case 1750a029a4eaSThomas Richter * CPU Measurement Sampling Facility is turned off. 1751a029a4eaSThomas Richter */ 17524efd417fSVasily Gorbik mhz = __ecag(ECAG_CPU_ATTRIBUTE, 0); 1753a029a4eaSThomas Richter if (mhz != -1UL) 1754a029a4eaSThomas Richter cfdiag_cpu_speed = mhz & 0xffffffff; 1755a029a4eaSThomas Richter } 1756a029a4eaSThomas Richter 1757a029a4eaSThomas Richter static int cfset_init(void) 1758a029a4eaSThomas Richter { 1759a029a4eaSThomas Richter struct cpumf_ctr_info info; 1760a029a4eaSThomas Richter size_t need; 1761a029a4eaSThomas Richter int rc; 1762a029a4eaSThomas Richter 1763a029a4eaSThomas Richter if (qctri(&info)) 1764a029a4eaSThomas Richter return -ENODEV; 1765a029a4eaSThomas Richter 1766a029a4eaSThomas Richter cfdiag_get_cpu_speed(); 1767a029a4eaSThomas Richter /* Make sure the counter set data fits into predefined buffer. */ 1768a029a4eaSThomas Richter need = cfdiag_maxsize(&info); 1769a029a4eaSThomas Richter if (need > sizeof(((struct cpu_cf_events *)0)->start)) { 1770a029a4eaSThomas Richter pr_err("Insufficient memory for PMU(cpum_cf_diag) need=%zu\n", 1771a029a4eaSThomas Richter need); 1772a029a4eaSThomas Richter return -ENOMEM; 1773a029a4eaSThomas Richter } 1774a029a4eaSThomas Richter 1775a029a4eaSThomas Richter rc = misc_register(&cfset_dev); 1776a029a4eaSThomas Richter if (rc) { 1777a029a4eaSThomas Richter pr_err("Registration of /dev/%s failed rc=%i\n", 1778a029a4eaSThomas Richter cfset_dev.name, rc); 1779a029a4eaSThomas Richter goto out; 1780a029a4eaSThomas Richter } 1781a029a4eaSThomas Richter 1782a029a4eaSThomas Richter rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", -1); 1783a029a4eaSThomas Richter if (rc) { 1784a029a4eaSThomas Richter misc_deregister(&cfset_dev); 1785a029a4eaSThomas Richter pr_err("Registration of PMU(cpum_cf_diag) failed with rc=%i\n", 1786a029a4eaSThomas Richter rc); 1787a029a4eaSThomas Richter } 1788a029a4eaSThomas Richter out: 1789a029a4eaSThomas Richter return rc; 1790a029a4eaSThomas Richter } 1791a029a4eaSThomas Richter 1792a029a4eaSThomas Richter device_initcall(cpumf_pmu_init); 1793