1a17ae4c3SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2212188a5SHendrik Brueckner /* 3212188a5SHendrik Brueckner * Performance event support for s390x - CPU-measurement Counter Facility 4212188a5SHendrik Brueckner * 5a029a4eaSThomas Richter * Copyright IBM Corp. 2012, 2021 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> 19a029a4eaSThomas Richter 2030e145f8SHendrik Brueckner #include <asm/cpu_mcf.h> 21a029a4eaSThomas Richter #include <asm/hwctrset.h> 22a029a4eaSThomas Richter #include <asm/debug.h> 23a029a4eaSThomas Richter 24a029a4eaSThomas Richter static unsigned int cfdiag_cpu_speed; /* CPU speed for CF_DIAG trailer */ 25a029a4eaSThomas Richter static debug_info_t *cf_dbg; 26a029a4eaSThomas Richter 27a029a4eaSThomas Richter #define CF_DIAG_CTRSET_DEF 0xfeef /* Counter set header mark */ 28a029a4eaSThomas Richter /* interval in seconds */ 29a029a4eaSThomas Richter 30a029a4eaSThomas Richter /* Counter sets are stored as data stream in a page sized memory buffer and 31a029a4eaSThomas Richter * exported to user space via raw data attached to the event sample data. 32a029a4eaSThomas Richter * Each counter set starts with an eight byte header consisting of: 33a029a4eaSThomas Richter * - a two byte eye catcher (0xfeef) 34a029a4eaSThomas Richter * - a one byte counter set number 35a029a4eaSThomas Richter * - a two byte counter set size (indicates the number of counters in this set) 36a029a4eaSThomas Richter * - a three byte reserved value (must be zero) to make the header the same 37a029a4eaSThomas Richter * size as a counter value. 38a029a4eaSThomas Richter * All counter values are eight byte in size. 39a029a4eaSThomas Richter * 40a029a4eaSThomas Richter * All counter sets are followed by a 64 byte trailer. 41a029a4eaSThomas Richter * The trailer consists of a: 42a029a4eaSThomas Richter * - flag field indicating valid fields when corresponding bit set 43a029a4eaSThomas Richter * - the counter facility first and second version number 44a029a4eaSThomas Richter * - the CPU speed if nonzero 45a029a4eaSThomas Richter * - the time stamp the counter sets have been collected 46a029a4eaSThomas Richter * - the time of day (TOD) base value 47a029a4eaSThomas Richter * - the machine type. 48a029a4eaSThomas Richter * 49a029a4eaSThomas Richter * The counter sets are saved when the process is prepared to be executed on a 50a029a4eaSThomas Richter * CPU and saved again when the process is going to be removed from a CPU. 51a029a4eaSThomas Richter * The difference of both counter sets are calculated and stored in the event 52a029a4eaSThomas Richter * sample data area. 53a029a4eaSThomas Richter */ 54a029a4eaSThomas Richter struct cf_ctrset_entry { /* CPU-M CF counter set entry (8 byte) */ 55a029a4eaSThomas Richter unsigned int def:16; /* 0-15 Data Entry Format */ 56a029a4eaSThomas Richter unsigned int set:16; /* 16-31 Counter set identifier */ 57a029a4eaSThomas Richter unsigned int ctr:16; /* 32-47 Number of stored counters */ 58a029a4eaSThomas Richter unsigned int res1:16; /* 48-63 Reserved */ 59a029a4eaSThomas Richter }; 60a029a4eaSThomas Richter 61a029a4eaSThomas Richter struct cf_trailer_entry { /* CPU-M CF_DIAG trailer (64 byte) */ 62a029a4eaSThomas Richter /* 0 - 7 */ 63a029a4eaSThomas Richter union { 64a029a4eaSThomas Richter struct { 65a029a4eaSThomas Richter unsigned int clock_base:1; /* TOD clock base set */ 66a029a4eaSThomas Richter unsigned int speed:1; /* CPU speed set */ 67a029a4eaSThomas Richter /* Measurement alerts */ 68a029a4eaSThomas Richter unsigned int mtda:1; /* Loss of MT ctr. data alert */ 69a029a4eaSThomas Richter unsigned int caca:1; /* Counter auth. change alert */ 70a029a4eaSThomas Richter unsigned int lcda:1; /* Loss of counter data alert */ 71a029a4eaSThomas Richter }; 72a029a4eaSThomas Richter unsigned long flags; /* 0-63 All indicators */ 73a029a4eaSThomas Richter }; 74a029a4eaSThomas Richter /* 8 - 15 */ 75a029a4eaSThomas Richter unsigned int cfvn:16; /* 64-79 Ctr First Version */ 76a029a4eaSThomas Richter unsigned int csvn:16; /* 80-95 Ctr Second Version */ 77a029a4eaSThomas Richter unsigned int cpu_speed:32; /* 96-127 CPU speed */ 78a029a4eaSThomas Richter /* 16 - 23 */ 79a029a4eaSThomas Richter unsigned long timestamp; /* 128-191 Timestamp (TOD) */ 80a029a4eaSThomas Richter /* 24 - 55 */ 81a029a4eaSThomas Richter union { 82a029a4eaSThomas Richter struct { 83a029a4eaSThomas Richter unsigned long progusage1; 84a029a4eaSThomas Richter unsigned long progusage2; 85a029a4eaSThomas Richter unsigned long progusage3; 86a029a4eaSThomas Richter unsigned long tod_base; 87a029a4eaSThomas Richter }; 88a029a4eaSThomas Richter unsigned long progusage[4]; 89a029a4eaSThomas Richter }; 90a029a4eaSThomas Richter /* 56 - 63 */ 91a029a4eaSThomas Richter unsigned int mach_type:16; /* Machine type */ 92a029a4eaSThomas Richter unsigned int res1:16; /* Reserved */ 93a029a4eaSThomas Richter unsigned int res2:32; /* Reserved */ 94a029a4eaSThomas Richter }; 95a029a4eaSThomas Richter 96a029a4eaSThomas Richter /* Create the trailer data at the end of a page. */ 97a029a4eaSThomas Richter static void cfdiag_trailer(struct cf_trailer_entry *te) 98a029a4eaSThomas Richter { 99a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 100a029a4eaSThomas Richter struct cpuid cpuid; 101a029a4eaSThomas Richter 102a029a4eaSThomas Richter te->cfvn = cpuhw->info.cfvn; /* Counter version numbers */ 103a029a4eaSThomas Richter te->csvn = cpuhw->info.csvn; 104a029a4eaSThomas Richter 105a029a4eaSThomas Richter get_cpu_id(&cpuid); /* Machine type */ 106a029a4eaSThomas Richter te->mach_type = cpuid.machine; 107a029a4eaSThomas Richter te->cpu_speed = cfdiag_cpu_speed; 108a029a4eaSThomas Richter if (te->cpu_speed) 109a029a4eaSThomas Richter te->speed = 1; 110a029a4eaSThomas Richter te->clock_base = 1; /* Save clock base */ 111a029a4eaSThomas Richter te->tod_base = tod_clock_base.tod; 112a029a4eaSThomas Richter te->timestamp = get_tod_clock_fast(); 113a029a4eaSThomas Richter } 114a029a4eaSThomas Richter 115a029a4eaSThomas Richter /* Read a counter set. The counter set number determines the counter set and 116a029a4eaSThomas Richter * the CPUM-CF first and second version number determine the number of 117a029a4eaSThomas Richter * available counters in each counter set. 118a029a4eaSThomas Richter * Each counter set starts with header containing the counter set number and 119a029a4eaSThomas Richter * the number of eight byte counters. 120a029a4eaSThomas Richter * 121a029a4eaSThomas Richter * The functions returns the number of bytes occupied by this counter set 122a029a4eaSThomas Richter * including the header. 123a029a4eaSThomas Richter * If there is no counter in the counter set, this counter set is useless and 124a029a4eaSThomas Richter * zero is returned on this case. 125a029a4eaSThomas Richter * 126a029a4eaSThomas Richter * Note that the counter sets may not be enabled or active and the stcctm 127a029a4eaSThomas Richter * instruction might return error 3. Depending on error_ok value this is ok, 128a029a4eaSThomas Richter * for example when called from cpumf_pmu_start() call back function. 129a029a4eaSThomas Richter */ 130a029a4eaSThomas Richter static size_t cfdiag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset, 131a029a4eaSThomas Richter size_t room, bool error_ok) 132a029a4eaSThomas Richter { 133a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 134a029a4eaSThomas Richter size_t ctrset_size, need = 0; 135a029a4eaSThomas Richter int rc = 3; /* Assume write failure */ 136a029a4eaSThomas Richter 137a029a4eaSThomas Richter ctrdata->def = CF_DIAG_CTRSET_DEF; 138a029a4eaSThomas Richter ctrdata->set = ctrset; 139a029a4eaSThomas Richter ctrdata->res1 = 0; 140a029a4eaSThomas Richter ctrset_size = cpum_cf_ctrset_size(ctrset, &cpuhw->info); 141a029a4eaSThomas Richter 142a029a4eaSThomas Richter if (ctrset_size) { /* Save data */ 143a029a4eaSThomas Richter need = ctrset_size * sizeof(u64) + sizeof(*ctrdata); 144a029a4eaSThomas Richter if (need <= room) { 145a029a4eaSThomas Richter rc = ctr_stcctm(ctrset, ctrset_size, 146a029a4eaSThomas Richter (u64 *)(ctrdata + 1)); 147a029a4eaSThomas Richter } 148a029a4eaSThomas Richter if (rc != 3 || error_ok) 149a029a4eaSThomas Richter ctrdata->ctr = ctrset_size; 150a029a4eaSThomas Richter else 151a029a4eaSThomas Richter need = 0; 152a029a4eaSThomas Richter } 153a029a4eaSThomas Richter 154a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, 155a029a4eaSThomas Richter "%s ctrset %d ctrset_size %zu cfvn %d csvn %d" 156a029a4eaSThomas Richter " need %zd rc %d\n", __func__, ctrset, ctrset_size, 157a029a4eaSThomas Richter cpuhw->info.cfvn, cpuhw->info.csvn, need, rc); 158a029a4eaSThomas Richter return need; 159a029a4eaSThomas Richter } 160a029a4eaSThomas Richter 161a029a4eaSThomas Richter /* Read out all counter sets and save them in the provided data buffer. 162a029a4eaSThomas Richter * The last 64 byte host an artificial trailer entry. 163a029a4eaSThomas Richter */ 164a029a4eaSThomas Richter static size_t cfdiag_getctr(void *data, size_t sz, unsigned long auth, 165a029a4eaSThomas Richter bool error_ok) 166a029a4eaSThomas Richter { 167a029a4eaSThomas Richter struct cf_trailer_entry *trailer; 168a029a4eaSThomas Richter size_t offset = 0, done; 169a029a4eaSThomas Richter int i; 170a029a4eaSThomas Richter 171a029a4eaSThomas Richter memset(data, 0, sz); 172a029a4eaSThomas Richter sz -= sizeof(*trailer); /* Always room for trailer */ 173a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 174a029a4eaSThomas Richter struct cf_ctrset_entry *ctrdata = data + offset; 175a029a4eaSThomas Richter 176a029a4eaSThomas Richter if (!(auth & cpumf_ctr_ctl[i])) 177a029a4eaSThomas Richter continue; /* Counter set not authorized */ 178a029a4eaSThomas Richter 179a029a4eaSThomas Richter done = cfdiag_getctrset(ctrdata, i, sz - offset, error_ok); 180a029a4eaSThomas Richter offset += done; 181a029a4eaSThomas Richter } 182a029a4eaSThomas Richter trailer = data + offset; 183a029a4eaSThomas Richter cfdiag_trailer(trailer); 184a029a4eaSThomas Richter return offset + sizeof(*trailer); 185a029a4eaSThomas Richter } 186a029a4eaSThomas Richter 187a029a4eaSThomas Richter /* Calculate the difference for each counter in a counter set. */ 188a029a4eaSThomas Richter static void cfdiag_diffctrset(u64 *pstart, u64 *pstop, int counters) 189a029a4eaSThomas Richter { 190a029a4eaSThomas Richter for (; --counters >= 0; ++pstart, ++pstop) 191a029a4eaSThomas Richter if (*pstop >= *pstart) 192a029a4eaSThomas Richter *pstop -= *pstart; 193a029a4eaSThomas Richter else 194a029a4eaSThomas Richter *pstop = *pstart - *pstop + 1; 195a029a4eaSThomas Richter } 196a029a4eaSThomas Richter 197a029a4eaSThomas Richter /* Scan the counter sets and calculate the difference of each counter 198a029a4eaSThomas Richter * in each set. The result is the increment of each counter during the 199a029a4eaSThomas Richter * period the counter set has been activated. 200a029a4eaSThomas Richter * 201a029a4eaSThomas Richter * Return true on success. 202a029a4eaSThomas Richter */ 203a029a4eaSThomas Richter static int cfdiag_diffctr(struct cpu_cf_events *cpuhw, unsigned long auth) 204a029a4eaSThomas Richter { 205a029a4eaSThomas Richter struct cf_trailer_entry *trailer_start, *trailer_stop; 206a029a4eaSThomas Richter struct cf_ctrset_entry *ctrstart, *ctrstop; 207a029a4eaSThomas Richter size_t offset = 0; 208a029a4eaSThomas Richter 209a029a4eaSThomas Richter auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1; 210a029a4eaSThomas Richter do { 211a029a4eaSThomas Richter ctrstart = (struct cf_ctrset_entry *)(cpuhw->start + offset); 212a029a4eaSThomas Richter ctrstop = (struct cf_ctrset_entry *)(cpuhw->stop + offset); 213a029a4eaSThomas Richter 214a029a4eaSThomas Richter if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) { 215a029a4eaSThomas Richter pr_err_once("cpum_cf_diag counter set compare error " 216a029a4eaSThomas Richter "in set %i\n", ctrstart->set); 217a029a4eaSThomas Richter return 0; 218a029a4eaSThomas Richter } 219a029a4eaSThomas Richter auth &= ~cpumf_ctr_ctl[ctrstart->set]; 220a029a4eaSThomas Richter if (ctrstart->def == CF_DIAG_CTRSET_DEF) { 221a029a4eaSThomas Richter cfdiag_diffctrset((u64 *)(ctrstart + 1), 222a029a4eaSThomas Richter (u64 *)(ctrstop + 1), ctrstart->ctr); 223a029a4eaSThomas Richter offset += ctrstart->ctr * sizeof(u64) + 224a029a4eaSThomas Richter sizeof(*ctrstart); 225a029a4eaSThomas Richter } 226a029a4eaSThomas Richter } while (ctrstart->def && auth); 227a029a4eaSThomas Richter 228a029a4eaSThomas Richter /* Save time_stamp from start of event in stop's trailer */ 229a029a4eaSThomas Richter trailer_start = (struct cf_trailer_entry *)(cpuhw->start + offset); 230a029a4eaSThomas Richter trailer_stop = (struct cf_trailer_entry *)(cpuhw->stop + offset); 231a029a4eaSThomas Richter trailer_stop->progusage[0] = trailer_start->timestamp; 232a029a4eaSThomas Richter 233a029a4eaSThomas Richter return 1; 234a029a4eaSThomas Richter } 235212188a5SHendrik Brueckner 236ee699f32SHendrik Brueckner static enum cpumf_ctr_set get_counter_set(u64 event) 237212188a5SHendrik Brueckner { 238ee699f32SHendrik Brueckner int set = CPUMF_CTR_SET_MAX; 239212188a5SHendrik Brueckner 240212188a5SHendrik Brueckner if (event < 32) 241212188a5SHendrik Brueckner set = CPUMF_CTR_SET_BASIC; 242212188a5SHendrik Brueckner else if (event < 64) 243212188a5SHendrik Brueckner set = CPUMF_CTR_SET_USER; 244212188a5SHendrik Brueckner else if (event < 128) 245212188a5SHendrik Brueckner set = CPUMF_CTR_SET_CRYPTO; 24646a984ffSThomas Richter else if (event < 288) 247212188a5SHendrik Brueckner set = CPUMF_CTR_SET_EXT; 248ee699f32SHendrik Brueckner else if (event >= 448 && event < 496) 249ee699f32SHendrik Brueckner set = CPUMF_CTR_SET_MT_DIAG; 250212188a5SHendrik Brueckner 251212188a5SHendrik Brueckner return set; 252212188a5SHendrik Brueckner } 253212188a5SHendrik Brueckner 254a029a4eaSThomas Richter static int validate_ctr_version(const struct hw_perf_event *hwc, 255a029a4eaSThomas Richter enum cpumf_ctr_set set) 256212188a5SHendrik Brueckner { 257f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw; 258212188a5SHendrik Brueckner int err = 0; 259ee699f32SHendrik Brueckner u16 mtdiag_ctl; 260212188a5SHendrik Brueckner 261f1c0b831SHendrik Brueckner cpuhw = &get_cpu_var(cpu_cf_events); 262212188a5SHendrik Brueckner 263212188a5SHendrik Brueckner /* check required version for counter sets */ 264a029a4eaSThomas Richter switch (set) { 265212188a5SHendrik Brueckner case CPUMF_CTR_SET_BASIC: 266212188a5SHendrik Brueckner case CPUMF_CTR_SET_USER: 267212188a5SHendrik Brueckner if (cpuhw->info.cfvn < 1) 268212188a5SHendrik Brueckner err = -EOPNOTSUPP; 269212188a5SHendrik Brueckner break; 270212188a5SHendrik Brueckner case CPUMF_CTR_SET_CRYPTO: 27146a984ffSThomas Richter if ((cpuhw->info.csvn >= 1 && cpuhw->info.csvn <= 5 && 27246a984ffSThomas Richter hwc->config > 79) || 27346a984ffSThomas Richter (cpuhw->info.csvn >= 6 && hwc->config > 83)) 27446a984ffSThomas Richter err = -EOPNOTSUPP; 27546a984ffSThomas Richter break; 276212188a5SHendrik Brueckner case CPUMF_CTR_SET_EXT: 277212188a5SHendrik Brueckner if (cpuhw->info.csvn < 1) 278212188a5SHendrik Brueckner err = -EOPNOTSUPP; 279f47586b2SHendrik Brueckner if ((cpuhw->info.csvn == 1 && hwc->config > 159) || 280f47586b2SHendrik Brueckner (cpuhw->info.csvn == 2 && hwc->config > 175) || 28146a984ffSThomas Richter (cpuhw->info.csvn >= 3 && cpuhw->info.csvn <= 5 28246a984ffSThomas Richter && hwc->config > 255) || 28346a984ffSThomas Richter (cpuhw->info.csvn >= 6 && hwc->config > 287)) 284f47586b2SHendrik Brueckner err = -EOPNOTSUPP; 285212188a5SHendrik Brueckner break; 286ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MT_DIAG: 287ee699f32SHendrik Brueckner if (cpuhw->info.csvn <= 3) 288ee699f32SHendrik Brueckner err = -EOPNOTSUPP; 289ee699f32SHendrik Brueckner /* 290ee699f32SHendrik Brueckner * MT-diagnostic counters are read-only. The counter set 291ee699f32SHendrik Brueckner * is automatically enabled and activated on all CPUs with 292ee699f32SHendrik Brueckner * multithreading (SMT). Deactivation of multithreading 293ee699f32SHendrik Brueckner * also disables the counter set. State changes are ignored 294ee699f32SHendrik Brueckner * by lcctl(). Because Linux controls SMT enablement through 295ee699f32SHendrik Brueckner * a kernel parameter only, the counter set is either disabled 296ee699f32SHendrik Brueckner * or enabled and active. 297ee699f32SHendrik Brueckner * 298ee699f32SHendrik Brueckner * Thus, the counters can only be used if SMT is on and the 299ee699f32SHendrik Brueckner * counter set is enabled and active. 300ee699f32SHendrik Brueckner */ 30130e145f8SHendrik Brueckner mtdiag_ctl = cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG]; 302ee699f32SHendrik Brueckner if (!((cpuhw->info.auth_ctl & mtdiag_ctl) && 303ee699f32SHendrik Brueckner (cpuhw->info.enable_ctl & mtdiag_ctl) && 304ee699f32SHendrik Brueckner (cpuhw->info.act_ctl & mtdiag_ctl))) 305ee699f32SHendrik Brueckner err = -EOPNOTSUPP; 306ee699f32SHendrik Brueckner break; 307a029a4eaSThomas Richter case CPUMF_CTR_SET_MAX: 308a029a4eaSThomas Richter err = -EOPNOTSUPP; 309212188a5SHendrik Brueckner } 310212188a5SHendrik Brueckner 311f1c0b831SHendrik Brueckner put_cpu_var(cpu_cf_events); 312212188a5SHendrik Brueckner return err; 313212188a5SHendrik Brueckner } 314212188a5SHendrik Brueckner 315212188a5SHendrik Brueckner static int validate_ctr_auth(const struct hw_perf_event *hwc) 316212188a5SHendrik Brueckner { 317f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw; 318212188a5SHendrik Brueckner int err = 0; 319212188a5SHendrik Brueckner 320f1c0b831SHendrik Brueckner cpuhw = &get_cpu_var(cpu_cf_events); 321212188a5SHendrik Brueckner 32258f8e9daSHendrik Brueckner /* Check authorization for cpu counter sets. 32358f8e9daSHendrik Brueckner * If the particular CPU counter set is not authorized, 32458f8e9daSHendrik Brueckner * return with -ENOENT in order to fall back to other 32558f8e9daSHendrik Brueckner * PMUs that might suffice the event request. 32658f8e9daSHendrik Brueckner */ 327a029a4eaSThomas Richter if (!(hwc->config_base & cpuhw->info.auth_ctl)) 32858f8e9daSHendrik Brueckner err = -ENOENT; 329212188a5SHendrik Brueckner 330f1c0b831SHendrik Brueckner put_cpu_var(cpu_cf_events); 331212188a5SHendrik Brueckner return err; 332212188a5SHendrik Brueckner } 333212188a5SHendrik Brueckner 334212188a5SHendrik Brueckner /* 335212188a5SHendrik Brueckner * Change the CPUMF state to active. 336212188a5SHendrik Brueckner * Enable and activate the CPU-counter sets according 337212188a5SHendrik Brueckner * to the per-cpu control state. 338212188a5SHendrik Brueckner */ 339212188a5SHendrik Brueckner static void cpumf_pmu_enable(struct pmu *pmu) 340212188a5SHendrik Brueckner { 341f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 342212188a5SHendrik Brueckner int err; 343212188a5SHendrik Brueckner 344212188a5SHendrik Brueckner if (cpuhw->flags & PMU_F_ENABLED) 345212188a5SHendrik Brueckner return; 346212188a5SHendrik Brueckner 347a029a4eaSThomas Richter err = lcctl(cpuhw->state | cpuhw->dev_state); 348212188a5SHendrik Brueckner if (err) { 349212188a5SHendrik Brueckner pr_err("Enabling the performance measuring unit " 350af0ee94eSHeiko Carstens "failed with rc=%x\n", err); 351212188a5SHendrik Brueckner return; 352212188a5SHendrik Brueckner } 353212188a5SHendrik Brueckner 354212188a5SHendrik Brueckner cpuhw->flags |= PMU_F_ENABLED; 355212188a5SHendrik Brueckner } 356212188a5SHendrik Brueckner 357212188a5SHendrik Brueckner /* 358212188a5SHendrik Brueckner * Change the CPUMF state to inactive. 359212188a5SHendrik Brueckner * Disable and enable (inactive) the CPU-counter sets according 360212188a5SHendrik Brueckner * to the per-cpu control state. 361212188a5SHendrik Brueckner */ 362212188a5SHendrik Brueckner static void cpumf_pmu_disable(struct pmu *pmu) 363212188a5SHendrik Brueckner { 364f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 365212188a5SHendrik Brueckner int err; 366212188a5SHendrik Brueckner u64 inactive; 367212188a5SHendrik Brueckner 368212188a5SHendrik Brueckner if (!(cpuhw->flags & PMU_F_ENABLED)) 369212188a5SHendrik Brueckner return; 370212188a5SHendrik Brueckner 371212188a5SHendrik Brueckner inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1); 372a029a4eaSThomas Richter inactive |= cpuhw->dev_state; 373212188a5SHendrik Brueckner err = lcctl(inactive); 374212188a5SHendrik Brueckner if (err) { 375212188a5SHendrik Brueckner pr_err("Disabling the performance measuring unit " 376af0ee94eSHeiko Carstens "failed with rc=%x\n", err); 377212188a5SHendrik Brueckner return; 378212188a5SHendrik Brueckner } 379212188a5SHendrik Brueckner 380212188a5SHendrik Brueckner cpuhw->flags &= ~PMU_F_ENABLED; 381212188a5SHendrik Brueckner } 382212188a5SHendrik Brueckner 383212188a5SHendrik Brueckner 384212188a5SHendrik Brueckner /* Number of perf events counting hardware events */ 385212188a5SHendrik Brueckner static atomic_t num_events = ATOMIC_INIT(0); 386212188a5SHendrik Brueckner /* Used to avoid races in calling reserve/release_cpumf_hardware */ 387212188a5SHendrik Brueckner static DEFINE_MUTEX(pmc_reserve_mutex); 388212188a5SHendrik Brueckner 389212188a5SHendrik Brueckner /* Release the PMU if event is the last perf event */ 390212188a5SHendrik Brueckner static void hw_perf_event_destroy(struct perf_event *event) 391212188a5SHendrik Brueckner { 392212188a5SHendrik Brueckner if (!atomic_add_unless(&num_events, -1, 1)) { 393212188a5SHendrik Brueckner mutex_lock(&pmc_reserve_mutex); 394212188a5SHendrik Brueckner if (atomic_dec_return(&num_events) == 0) 3953d33345aSHendrik Brueckner __kernel_cpumcf_end(); 396212188a5SHendrik Brueckner mutex_unlock(&pmc_reserve_mutex); 397212188a5SHendrik Brueckner } 398212188a5SHendrik Brueckner } 399212188a5SHendrik Brueckner 400212188a5SHendrik Brueckner /* CPUMF <-> perf event mappings for kernel+userspace (basic set) */ 401212188a5SHendrik Brueckner static const int cpumf_generic_events_basic[] = { 402212188a5SHendrik Brueckner [PERF_COUNT_HW_CPU_CYCLES] = 0, 403212188a5SHendrik Brueckner [PERF_COUNT_HW_INSTRUCTIONS] = 1, 404212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_REFERENCES] = -1, 405212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_MISSES] = -1, 406212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1, 407212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_MISSES] = -1, 408212188a5SHendrik Brueckner [PERF_COUNT_HW_BUS_CYCLES] = -1, 409212188a5SHendrik Brueckner }; 410212188a5SHendrik Brueckner /* CPUMF <-> perf event mappings for userspace (problem-state set) */ 411212188a5SHendrik Brueckner static const int cpumf_generic_events_user[] = { 412212188a5SHendrik Brueckner [PERF_COUNT_HW_CPU_CYCLES] = 32, 413212188a5SHendrik Brueckner [PERF_COUNT_HW_INSTRUCTIONS] = 33, 414212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_REFERENCES] = -1, 415212188a5SHendrik Brueckner [PERF_COUNT_HW_CACHE_MISSES] = -1, 416212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1, 417212188a5SHendrik Brueckner [PERF_COUNT_HW_BRANCH_MISSES] = -1, 418212188a5SHendrik Brueckner [PERF_COUNT_HW_BUS_CYCLES] = -1, 419212188a5SHendrik Brueckner }; 420212188a5SHendrik Brueckner 421a029a4eaSThomas Richter static void cpumf_hw_inuse(void) 422a029a4eaSThomas Richter { 423a029a4eaSThomas Richter mutex_lock(&pmc_reserve_mutex); 424a029a4eaSThomas Richter if (atomic_inc_return(&num_events) == 1) 425a029a4eaSThomas Richter __kernel_cpumcf_begin(); 426a029a4eaSThomas Richter mutex_unlock(&pmc_reserve_mutex); 427a029a4eaSThomas Richter } 428a029a4eaSThomas Richter 4296a82e23fSThomas Richter static int __hw_perf_event_init(struct perf_event *event, unsigned int type) 430212188a5SHendrik Brueckner { 431212188a5SHendrik Brueckner struct perf_event_attr *attr = &event->attr; 432212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 433ee699f32SHendrik Brueckner enum cpumf_ctr_set set; 43447b74785SThomas Richter int err = 0; 435212188a5SHendrik Brueckner u64 ev; 436212188a5SHendrik Brueckner 4376a82e23fSThomas Richter switch (type) { 438212188a5SHendrik Brueckner case PERF_TYPE_RAW: 439212188a5SHendrik Brueckner /* Raw events are used to access counters directly, 440212188a5SHendrik Brueckner * hence do not permit excludes */ 441212188a5SHendrik Brueckner if (attr->exclude_kernel || attr->exclude_user || 442212188a5SHendrik Brueckner attr->exclude_hv) 443212188a5SHendrik Brueckner return -EOPNOTSUPP; 444212188a5SHendrik Brueckner ev = attr->config; 445212188a5SHendrik Brueckner break; 446212188a5SHendrik Brueckner 447212188a5SHendrik Brueckner case PERF_TYPE_HARDWARE: 448613a41b0SThomas Richter if (is_sampling_event(event)) /* No sampling support */ 449613a41b0SThomas Richter return -ENOENT; 450212188a5SHendrik Brueckner ev = attr->config; 451212188a5SHendrik Brueckner /* Count user space (problem-state) only */ 452212188a5SHendrik Brueckner if (!attr->exclude_user && attr->exclude_kernel) { 453212188a5SHendrik Brueckner if (ev >= ARRAY_SIZE(cpumf_generic_events_user)) 454212188a5SHendrik Brueckner return -EOPNOTSUPP; 455212188a5SHendrik Brueckner ev = cpumf_generic_events_user[ev]; 456212188a5SHendrik Brueckner 457212188a5SHendrik Brueckner /* No support for kernel space counters only */ 458212188a5SHendrik Brueckner } else if (!attr->exclude_kernel && attr->exclude_user) { 459212188a5SHendrik Brueckner return -EOPNOTSUPP; 4600cceeab5SThomas Richter } else { /* Count user and kernel space */ 461212188a5SHendrik Brueckner if (ev >= ARRAY_SIZE(cpumf_generic_events_basic)) 462212188a5SHendrik Brueckner return -EOPNOTSUPP; 463212188a5SHendrik Brueckner ev = cpumf_generic_events_basic[ev]; 464212188a5SHendrik Brueckner } 465212188a5SHendrik Brueckner break; 466212188a5SHendrik Brueckner 467212188a5SHendrik Brueckner default: 468212188a5SHendrik Brueckner return -ENOENT; 469212188a5SHendrik Brueckner } 470212188a5SHendrik Brueckner 471212188a5SHendrik Brueckner if (ev == -1) 472212188a5SHendrik Brueckner return -ENOENT; 473212188a5SHendrik Brueckner 47420ba46daSHendrik Brueckner if (ev > PERF_CPUM_CF_MAX_CTR) 4750bb2ae1bSThomas Richter return -ENOENT; 476212188a5SHendrik Brueckner 477ee699f32SHendrik Brueckner /* Obtain the counter set to which the specified counter belongs */ 478ee699f32SHendrik Brueckner set = get_counter_set(ev); 479ee699f32SHendrik Brueckner switch (set) { 480ee699f32SHendrik Brueckner case CPUMF_CTR_SET_BASIC: 481ee699f32SHendrik Brueckner case CPUMF_CTR_SET_USER: 482ee699f32SHendrik Brueckner case CPUMF_CTR_SET_CRYPTO: 483ee699f32SHendrik Brueckner case CPUMF_CTR_SET_EXT: 484ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MT_DIAG: 485ee699f32SHendrik Brueckner /* 486ee699f32SHendrik Brueckner * Use the hardware perf event structure to store the 487ee699f32SHendrik Brueckner * counter number in the 'config' member and the counter 488a029a4eaSThomas Richter * set number in the 'config_base' as bit mask. 489a029a4eaSThomas Richter * It is later used to enable/disable the counter(s). 490212188a5SHendrik Brueckner */ 491212188a5SHendrik Brueckner hwc->config = ev; 492a029a4eaSThomas Richter hwc->config_base = cpumf_ctr_ctl[set]; 493ee699f32SHendrik Brueckner break; 494ee699f32SHendrik Brueckner case CPUMF_CTR_SET_MAX: 495ee699f32SHendrik Brueckner /* The counter could not be associated to a counter set */ 496ee699f32SHendrik Brueckner return -EINVAL; 4971c0a9c79SJiapeng Chong } 498212188a5SHendrik Brueckner 499212188a5SHendrik Brueckner /* Initialize for using the CPU-measurement counter facility */ 500a029a4eaSThomas Richter cpumf_hw_inuse(); 501212188a5SHendrik Brueckner event->destroy = hw_perf_event_destroy; 502212188a5SHendrik Brueckner 503212188a5SHendrik Brueckner /* Finally, validate version and authorization of the counter set */ 504212188a5SHendrik Brueckner err = validate_ctr_auth(hwc); 505212188a5SHendrik Brueckner if (!err) 506a029a4eaSThomas Richter err = validate_ctr_version(hwc, set); 507212188a5SHendrik Brueckner 508212188a5SHendrik Brueckner return err; 509212188a5SHendrik Brueckner } 510212188a5SHendrik Brueckner 511212188a5SHendrik Brueckner static int cpumf_pmu_event_init(struct perf_event *event) 512212188a5SHendrik Brueckner { 5136a82e23fSThomas Richter unsigned int type = event->attr.type; 514212188a5SHendrik Brueckner int err; 515212188a5SHendrik Brueckner 5166a82e23fSThomas Richter if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) 5176a82e23fSThomas Richter err = __hw_perf_event_init(event, type); 5186a82e23fSThomas Richter else if (event->pmu->type == type) 5196a82e23fSThomas Richter /* Registered as unknown PMU */ 5206a82e23fSThomas Richter err = __hw_perf_event_init(event, PERF_TYPE_RAW); 5216a82e23fSThomas Richter else 522212188a5SHendrik Brueckner return -ENOENT; 523212188a5SHendrik Brueckner 524212188a5SHendrik Brueckner if (unlikely(err) && event->destroy) 525212188a5SHendrik Brueckner event->destroy(event); 526212188a5SHendrik Brueckner 527212188a5SHendrik Brueckner return err; 528212188a5SHendrik Brueckner } 529212188a5SHendrik Brueckner 530212188a5SHendrik Brueckner static int hw_perf_event_reset(struct perf_event *event) 531212188a5SHendrik Brueckner { 532212188a5SHendrik Brueckner u64 prev, new; 533212188a5SHendrik Brueckner int err; 534212188a5SHendrik Brueckner 535212188a5SHendrik Brueckner do { 536212188a5SHendrik Brueckner prev = local64_read(&event->hw.prev_count); 537212188a5SHendrik Brueckner err = ecctr(event->hw.config, &new); 538212188a5SHendrik Brueckner if (err) { 539212188a5SHendrik Brueckner if (err != 3) 540212188a5SHendrik Brueckner break; 541212188a5SHendrik Brueckner /* The counter is not (yet) available. This 542212188a5SHendrik Brueckner * might happen if the counter set to which 543212188a5SHendrik Brueckner * this counter belongs is in the disabled 544212188a5SHendrik Brueckner * state. 545212188a5SHendrik Brueckner */ 546212188a5SHendrik Brueckner new = 0; 547212188a5SHendrik Brueckner } 548212188a5SHendrik Brueckner } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev); 549212188a5SHendrik Brueckner 550212188a5SHendrik Brueckner return err; 551212188a5SHendrik Brueckner } 552212188a5SHendrik Brueckner 553485527baSHendrik Brueckner static void hw_perf_event_update(struct perf_event *event) 554212188a5SHendrik Brueckner { 555212188a5SHendrik Brueckner u64 prev, new, delta; 556212188a5SHendrik Brueckner int err; 557212188a5SHendrik Brueckner 558212188a5SHendrik Brueckner do { 559212188a5SHendrik Brueckner prev = local64_read(&event->hw.prev_count); 560212188a5SHendrik Brueckner err = ecctr(event->hw.config, &new); 561212188a5SHendrik Brueckner if (err) 562485527baSHendrik Brueckner return; 563212188a5SHendrik Brueckner } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev); 564212188a5SHendrik Brueckner 565212188a5SHendrik Brueckner delta = (prev <= new) ? new - prev 566212188a5SHendrik Brueckner : (-1ULL - prev) + new + 1; /* overflow */ 567212188a5SHendrik Brueckner local64_add(delta, &event->count); 568212188a5SHendrik Brueckner } 569212188a5SHendrik Brueckner 570212188a5SHendrik Brueckner static void cpumf_pmu_read(struct perf_event *event) 571212188a5SHendrik Brueckner { 572212188a5SHendrik Brueckner if (event->hw.state & PERF_HES_STOPPED) 573212188a5SHendrik Brueckner return; 574212188a5SHendrik Brueckner 575212188a5SHendrik Brueckner hw_perf_event_update(event); 576212188a5SHendrik Brueckner } 577212188a5SHendrik Brueckner 578212188a5SHendrik Brueckner static void cpumf_pmu_start(struct perf_event *event, int flags) 579212188a5SHendrik Brueckner { 580f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 581212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 582a029a4eaSThomas Richter int i; 583212188a5SHendrik Brueckner 58415e5b53fSThomas Richter if (!(hwc->state & PERF_HES_STOPPED)) 585212188a5SHendrik Brueckner return; 586212188a5SHendrik Brueckner 587212188a5SHendrik Brueckner hwc->state = 0; 588212188a5SHendrik Brueckner 589212188a5SHendrik Brueckner /* (Re-)enable and activate the counter set */ 590212188a5SHendrik Brueckner ctr_set_enable(&cpuhw->state, hwc->config_base); 591212188a5SHendrik Brueckner ctr_set_start(&cpuhw->state, hwc->config_base); 592212188a5SHendrik Brueckner 593212188a5SHendrik Brueckner /* The counter set to which this counter belongs can be already active. 594212188a5SHendrik Brueckner * Because all counters in a set are active, the event->hw.prev_count 595212188a5SHendrik Brueckner * needs to be synchronized. At this point, the counter set can be in 596212188a5SHendrik Brueckner * the inactive or disabled state. 597212188a5SHendrik Brueckner */ 598a029a4eaSThomas Richter if (hwc->config == PERF_EVENT_CPUM_CF_DIAG) { 599a029a4eaSThomas Richter cpuhw->usedss = cfdiag_getctr(cpuhw->start, 600a029a4eaSThomas Richter sizeof(cpuhw->start), 601a029a4eaSThomas Richter hwc->config_base, true); 602a029a4eaSThomas Richter } else { 603212188a5SHendrik Brueckner hw_perf_event_reset(event); 604a029a4eaSThomas Richter } 605212188a5SHendrik Brueckner 606a029a4eaSThomas Richter /* Increment refcount for counter sets */ 607a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) 608a029a4eaSThomas Richter if ((hwc->config_base & cpumf_ctr_ctl[i])) 609a029a4eaSThomas Richter atomic_inc(&cpuhw->ctr_set[i]); 610a029a4eaSThomas Richter } 611a029a4eaSThomas Richter 612a029a4eaSThomas Richter /* Create perf event sample with the counter sets as raw data. The sample 613a029a4eaSThomas Richter * is then pushed to the event subsystem and the function checks for 614a029a4eaSThomas Richter * possible event overflows. If an event overflow occurs, the PMU is 615a029a4eaSThomas Richter * stopped. 616a029a4eaSThomas Richter * 617a029a4eaSThomas Richter * Return non-zero if an event overflow occurred. 618a029a4eaSThomas Richter */ 619a029a4eaSThomas Richter static int cfdiag_push_sample(struct perf_event *event, 620a029a4eaSThomas Richter struct cpu_cf_events *cpuhw) 621a029a4eaSThomas Richter { 622a029a4eaSThomas Richter struct perf_sample_data data; 623a029a4eaSThomas Richter struct perf_raw_record raw; 624a029a4eaSThomas Richter struct pt_regs regs; 625a029a4eaSThomas Richter int overflow; 626a029a4eaSThomas Richter 627a029a4eaSThomas Richter /* Setup perf sample */ 628a029a4eaSThomas Richter perf_sample_data_init(&data, 0, event->hw.last_period); 629a029a4eaSThomas Richter memset(®s, 0, sizeof(regs)); 630a029a4eaSThomas Richter memset(&raw, 0, sizeof(raw)); 631a029a4eaSThomas Richter 632a029a4eaSThomas Richter if (event->attr.sample_type & PERF_SAMPLE_CPU) 633a029a4eaSThomas Richter data.cpu_entry.cpu = event->cpu; 634a029a4eaSThomas Richter if (event->attr.sample_type & PERF_SAMPLE_RAW) { 635a029a4eaSThomas Richter raw.frag.size = cpuhw->usedss; 636a029a4eaSThomas Richter raw.frag.data = cpuhw->stop; 637a029a4eaSThomas Richter raw.size = raw.frag.size; 638a029a4eaSThomas Richter data.raw = &raw; 639a029a4eaSThomas Richter } 640a029a4eaSThomas Richter 641a029a4eaSThomas Richter overflow = perf_event_overflow(event, &data, ®s); 642a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, 643a029a4eaSThomas Richter "%s event %#llx sample_type %#llx raw %d ov %d\n", 644a029a4eaSThomas Richter __func__, event->hw.config, 645a029a4eaSThomas Richter event->attr.sample_type, raw.size, overflow); 646a029a4eaSThomas Richter if (overflow) 647a029a4eaSThomas Richter event->pmu->stop(event, 0); 648a029a4eaSThomas Richter 649a029a4eaSThomas Richter perf_event_update_userpage(event); 650a029a4eaSThomas Richter return overflow; 651212188a5SHendrik Brueckner } 652212188a5SHendrik Brueckner 653212188a5SHendrik Brueckner static void cpumf_pmu_stop(struct perf_event *event, int flags) 654212188a5SHendrik Brueckner { 655f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 656212188a5SHendrik Brueckner struct hw_perf_event *hwc = &event->hw; 657a029a4eaSThomas Richter int i; 658212188a5SHendrik Brueckner 659212188a5SHendrik Brueckner if (!(hwc->state & PERF_HES_STOPPED)) { 660212188a5SHendrik Brueckner /* Decrement reference count for this counter set and if this 661212188a5SHendrik Brueckner * is the last used counter in the set, clear activation 662212188a5SHendrik Brueckner * control and set the counter set state to inactive. 663212188a5SHendrik Brueckner */ 664a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 665a029a4eaSThomas Richter if (!(hwc->config_base & cpumf_ctr_ctl[i])) 666a029a4eaSThomas Richter continue; 667a029a4eaSThomas Richter if (!atomic_dec_return(&cpuhw->ctr_set[i])) 668a029a4eaSThomas Richter ctr_set_stop(&cpuhw->state, cpumf_ctr_ctl[i]); 669a029a4eaSThomas Richter } 6700cceeab5SThomas Richter hwc->state |= PERF_HES_STOPPED; 671212188a5SHendrik Brueckner } 672212188a5SHendrik Brueckner 673212188a5SHendrik Brueckner if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { 674a029a4eaSThomas Richter if (hwc->config == PERF_EVENT_CPUM_CF_DIAG) { 675a029a4eaSThomas Richter local64_inc(&event->count); 676a029a4eaSThomas Richter cpuhw->usedss = cfdiag_getctr(cpuhw->stop, 677a029a4eaSThomas Richter sizeof(cpuhw->stop), 678a029a4eaSThomas Richter event->hw.config_base, 679a029a4eaSThomas Richter false); 680a029a4eaSThomas Richter if (cfdiag_diffctr(cpuhw, event->hw.config_base)) 681a029a4eaSThomas Richter cfdiag_push_sample(event, cpuhw); 682a029a4eaSThomas Richter } else 683212188a5SHendrik Brueckner hw_perf_event_update(event); 6840cceeab5SThomas Richter hwc->state |= PERF_HES_UPTODATE; 685212188a5SHendrik Brueckner } 686212188a5SHendrik Brueckner } 687212188a5SHendrik Brueckner 688212188a5SHendrik Brueckner static int cpumf_pmu_add(struct perf_event *event, int flags) 689212188a5SHendrik Brueckner { 690f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 691212188a5SHendrik Brueckner 692212188a5SHendrik Brueckner ctr_set_enable(&cpuhw->state, event->hw.config_base); 693212188a5SHendrik Brueckner event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 694212188a5SHendrik Brueckner 695212188a5SHendrik Brueckner if (flags & PERF_EF_START) 696212188a5SHendrik Brueckner cpumf_pmu_start(event, PERF_EF_RELOAD); 697212188a5SHendrik Brueckner 698212188a5SHendrik Brueckner return 0; 699212188a5SHendrik Brueckner } 700212188a5SHendrik Brueckner 701212188a5SHendrik Brueckner static void cpumf_pmu_del(struct perf_event *event, int flags) 702212188a5SHendrik Brueckner { 703f1c0b831SHendrik Brueckner struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 704a029a4eaSThomas Richter int i; 705212188a5SHendrik Brueckner 706212188a5SHendrik Brueckner cpumf_pmu_stop(event, PERF_EF_UPDATE); 707212188a5SHendrik Brueckner 708212188a5SHendrik Brueckner /* Check if any counter in the counter set is still used. If not used, 709212188a5SHendrik Brueckner * change the counter set to the disabled state. This also clears the 710212188a5SHendrik Brueckner * content of all counters in the set. 711212188a5SHendrik Brueckner * 712212188a5SHendrik Brueckner * When a new perf event has been added but not yet started, this can 713212188a5SHendrik Brueckner * clear enable control and resets all counters in a set. Therefore, 714212188a5SHendrik Brueckner * cpumf_pmu_start() always has to reenable a counter set. 715212188a5SHendrik Brueckner */ 716a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) 717a029a4eaSThomas Richter if (!atomic_read(&cpuhw->ctr_set[i])) 718a029a4eaSThomas Richter ctr_set_disable(&cpuhw->state, cpumf_ctr_ctl[i]); 719212188a5SHendrik Brueckner } 720212188a5SHendrik Brueckner 721212188a5SHendrik Brueckner /* Performance monitoring unit for s390x */ 722212188a5SHendrik Brueckner static struct pmu cpumf_pmu = { 7239254e70cSHendrik Brueckner .task_ctx_nr = perf_sw_context, 7249254e70cSHendrik Brueckner .capabilities = PERF_PMU_CAP_NO_INTERRUPT, 725212188a5SHendrik Brueckner .pmu_enable = cpumf_pmu_enable, 726212188a5SHendrik Brueckner .pmu_disable = cpumf_pmu_disable, 727212188a5SHendrik Brueckner .event_init = cpumf_pmu_event_init, 728212188a5SHendrik Brueckner .add = cpumf_pmu_add, 729212188a5SHendrik Brueckner .del = cpumf_pmu_del, 730212188a5SHendrik Brueckner .start = cpumf_pmu_start, 731212188a5SHendrik Brueckner .stop = cpumf_pmu_stop, 732212188a5SHendrik Brueckner .read = cpumf_pmu_read, 733212188a5SHendrik Brueckner }; 734212188a5SHendrik Brueckner 735a029a4eaSThomas Richter static int cfset_init(void); 736212188a5SHendrik Brueckner static int __init cpumf_pmu_init(void) 737212188a5SHendrik Brueckner { 738212188a5SHendrik Brueckner int rc; 739212188a5SHendrik Brueckner 7407f5ac1a0SHendrik Brueckner if (!kernel_cpumcf_avail()) 741212188a5SHendrik Brueckner return -ENODEV; 742212188a5SHendrik Brueckner 743a029a4eaSThomas Richter /* Setup s390dbf facility */ 744a029a4eaSThomas Richter cf_dbg = debug_register(KMSG_COMPONENT, 2, 1, 128); 745a029a4eaSThomas Richter if (!cf_dbg) { 746a029a4eaSThomas Richter pr_err("Registration of s390dbf(cpum_cf) failed\n"); 747a029a4eaSThomas Richter return -ENOMEM; 7487d244643Skernel test robot } 749a029a4eaSThomas Richter debug_register_view(cf_dbg, &debug_sprintf_view); 750a029a4eaSThomas Richter 751c7168325SHendrik Brueckner cpumf_pmu.attr_groups = cpumf_cf_event_group(); 7526a82e23fSThomas Richter rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", -1); 753a029a4eaSThomas Richter if (rc) { 754a029a4eaSThomas Richter debug_unregister_view(cf_dbg, &debug_sprintf_view); 755a029a4eaSThomas Richter debug_unregister(cf_dbg); 756212188a5SHendrik Brueckner pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); 757a029a4eaSThomas Richter } else if (stccm_avail()) { /* Setup counter set device */ 758a029a4eaSThomas Richter cfset_init(); 759a029a4eaSThomas Richter } 760212188a5SHendrik Brueckner return rc; 761212188a5SHendrik Brueckner } 762a029a4eaSThomas Richter 763a029a4eaSThomas Richter /* Support for the CPU Measurement Facility counter set extraction using 764a029a4eaSThomas Richter * device /dev/hwctr. This allows user space programs to extract complete 765a029a4eaSThomas Richter * counter set via normal file operations. 766a029a4eaSThomas Richter */ 767a029a4eaSThomas Richter 768a029a4eaSThomas Richter static atomic_t cfset_opencnt = ATOMIC_INIT(0); /* Excl. access */ 769a029a4eaSThomas Richter static DEFINE_MUTEX(cfset_ctrset_mutex);/* Synchronize access to hardware */ 770a029a4eaSThomas Richter struct cfset_call_on_cpu_parm { /* Parm struct for smp_call_on_cpu */ 771a029a4eaSThomas Richter unsigned int sets; /* Counter set bit mask */ 772a029a4eaSThomas Richter atomic_t cpus_ack; /* # CPUs successfully executed func */ 773a029a4eaSThomas Richter }; 774a029a4eaSThomas Richter 775a029a4eaSThomas Richter static struct cfset_request { /* CPUs and counter set bit mask */ 776a029a4eaSThomas Richter unsigned long ctrset; /* Bit mask of counter set to read */ 777a029a4eaSThomas Richter cpumask_t mask; /* CPU mask to read from */ 778a029a4eaSThomas Richter } cfset_request; 779a029a4eaSThomas Richter 780a029a4eaSThomas Richter static void cfset_ctrset_clear(void) 781a029a4eaSThomas Richter { 782a029a4eaSThomas Richter cpumask_clear(&cfset_request.mask); 783a029a4eaSThomas Richter cfset_request.ctrset = 0; 784a029a4eaSThomas Richter } 785a029a4eaSThomas Richter 786a029a4eaSThomas Richter /* The /dev/hwctr device access uses PMU_F_IN_USE to mark the device access 787a029a4eaSThomas Richter * path is currently used. 788a029a4eaSThomas Richter * The cpu_cf_events::dev_state is used to denote counter sets in use by this 789a029a4eaSThomas Richter * interface. It is always or'ed in. If this interface is not active, its 790a029a4eaSThomas Richter * value is zero and no additional counter sets will be included. 791a029a4eaSThomas Richter * 792a029a4eaSThomas Richter * The cpu_cf_events::state is used by the perf_event_open SVC and remains 793a029a4eaSThomas Richter * unchanged. 794a029a4eaSThomas Richter * 795a029a4eaSThomas Richter * perf_pmu_enable() and perf_pmu_enable() and its call backs 796a029a4eaSThomas Richter * cpumf_pmu_enable() and cpumf_pmu_disable() are called by the 797a029a4eaSThomas Richter * performance measurement subsystem to enable per process 798a029a4eaSThomas Richter * CPU Measurement counter facility. 799a029a4eaSThomas Richter * The XXX_enable() and XXX_disable functions are used to turn off 800a029a4eaSThomas Richter * x86 performance monitoring interrupt (PMI) during scheduling. 801a029a4eaSThomas Richter * s390 uses these calls to temporarily stop and resume the active CPU 802a029a4eaSThomas Richter * counters sets during scheduling. 803a029a4eaSThomas Richter * 804a029a4eaSThomas Richter * We do allow concurrent access of perf_event_open() SVC and /dev/hwctr 805a029a4eaSThomas Richter * device access. The perf_event_open() SVC interface makes a lot of effort 806a029a4eaSThomas Richter * to only run the counters while the calling process is actively scheduled 807a029a4eaSThomas Richter * to run. 808a029a4eaSThomas Richter * When /dev/hwctr interface is also used at the same time, the counter sets 809a029a4eaSThomas Richter * will keep running, even when the process is scheduled off a CPU. 810a029a4eaSThomas Richter * However this is not a problem and does not lead to wrong counter values 811a029a4eaSThomas Richter * for the perf_event_open() SVC. The current counter value will be recorded 812a029a4eaSThomas Richter * during schedule-in. At schedule-out time the current counter value is 813a029a4eaSThomas Richter * extracted again and the delta is calculated and added to the event. 814a029a4eaSThomas Richter */ 815a029a4eaSThomas Richter /* Stop all counter sets via ioctl interface */ 816a029a4eaSThomas Richter static void cfset_ioctl_off(void *parm) 817a029a4eaSThomas Richter { 818a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 819a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 820a029a4eaSThomas Richter int rc; 821a029a4eaSThomas Richter 822a029a4eaSThomas Richter cpuhw->dev_state = 0; 823a029a4eaSThomas Richter for (rc = CPUMF_CTR_SET_BASIC; rc < CPUMF_CTR_SET_MAX; ++rc) 824a029a4eaSThomas Richter if ((p->sets & cpumf_ctr_ctl[rc])) 825a029a4eaSThomas Richter atomic_dec(&cpuhw->ctr_set[rc]); 826a029a4eaSThomas Richter rc = lcctl(cpuhw->state); /* Keep perf_event_open counter sets */ 827a029a4eaSThomas Richter if (rc) 828a029a4eaSThomas Richter pr_err("Counter set stop %#llx of /dev/%s failed rc=%i\n", 829a029a4eaSThomas Richter cpuhw->state, S390_HWCTR_DEVICE, rc); 830a029a4eaSThomas Richter cpuhw->flags &= ~PMU_F_IN_USE; 831a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s rc %d state %#llx dev_state %#llx\n", 832a029a4eaSThomas Richter __func__, rc, cpuhw->state, cpuhw->dev_state); 833a029a4eaSThomas Richter } 834a029a4eaSThomas Richter 835a029a4eaSThomas Richter /* Start counter sets on particular CPU */ 836a029a4eaSThomas Richter static void cfset_ioctl_on(void *parm) 837a029a4eaSThomas Richter { 838a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 839a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 840a029a4eaSThomas Richter int rc; 841a029a4eaSThomas Richter 842a029a4eaSThomas Richter cpuhw->flags |= PMU_F_IN_USE; 843a029a4eaSThomas Richter ctr_set_enable(&cpuhw->dev_state, p->sets); 844a029a4eaSThomas Richter ctr_set_start(&cpuhw->dev_state, p->sets); 845a029a4eaSThomas Richter for (rc = CPUMF_CTR_SET_BASIC; rc < CPUMF_CTR_SET_MAX; ++rc) 846a029a4eaSThomas Richter if ((p->sets & cpumf_ctr_ctl[rc])) 847a029a4eaSThomas Richter atomic_inc(&cpuhw->ctr_set[rc]); 848a029a4eaSThomas Richter rc = lcctl(cpuhw->dev_state | cpuhw->state); /* Start counter sets */ 849a029a4eaSThomas Richter if (!rc) 850a029a4eaSThomas Richter atomic_inc(&p->cpus_ack); 851a029a4eaSThomas Richter else 852a029a4eaSThomas Richter pr_err("Counter set start %#llx of /dev/%s failed rc=%i\n", 853a029a4eaSThomas Richter cpuhw->dev_state | cpuhw->state, S390_HWCTR_DEVICE, rc); 854a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s rc %d state %#llx dev_state %#llx\n", 855a029a4eaSThomas Richter __func__, rc, cpuhw->state, cpuhw->dev_state); 856a029a4eaSThomas Richter } 857a029a4eaSThomas Richter 858a029a4eaSThomas Richter static void cfset_release_cpu(void *p) 859a029a4eaSThomas Richter { 860a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 861a029a4eaSThomas Richter int rc; 862a029a4eaSThomas Richter 863a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s state %#llx dev_state %#llx\n", 864a029a4eaSThomas Richter __func__, cpuhw->state, cpuhw->dev_state); 865a029a4eaSThomas Richter rc = lcctl(cpuhw->state); /* Keep perf_event_open counter sets */ 866a029a4eaSThomas Richter if (rc) 867a029a4eaSThomas Richter pr_err("Counter set release %#llx of /dev/%s failed rc=%i\n", 868a029a4eaSThomas Richter cpuhw->state, S390_HWCTR_DEVICE, rc); 869a029a4eaSThomas Richter cpuhw->dev_state = 0; 870a029a4eaSThomas Richter } 871a029a4eaSThomas Richter 872a029a4eaSThomas Richter /* Release function is also called when application gets terminated without 873a029a4eaSThomas Richter * doing a proper ioctl(..., S390_HWCTR_STOP, ...) command. 874a029a4eaSThomas Richter */ 875a029a4eaSThomas Richter static int cfset_release(struct inode *inode, struct file *file) 876a029a4eaSThomas Richter { 877a029a4eaSThomas Richter on_each_cpu(cfset_release_cpu, NULL, 1); 878a029a4eaSThomas Richter hw_perf_event_destroy(NULL); 879a029a4eaSThomas Richter cfset_ctrset_clear(); 880a029a4eaSThomas Richter atomic_set(&cfset_opencnt, 0); 881a029a4eaSThomas Richter return 0; 882a029a4eaSThomas Richter } 883a029a4eaSThomas Richter 884a029a4eaSThomas Richter static int cfset_open(struct inode *inode, struct file *file) 885a029a4eaSThomas Richter { 886a029a4eaSThomas Richter if (!capable(CAP_SYS_ADMIN)) 887a029a4eaSThomas Richter return -EPERM; 888a029a4eaSThomas Richter /* Only one user space program can open /dev/hwctr */ 889a029a4eaSThomas Richter if (atomic_xchg(&cfset_opencnt, 1)) 890a029a4eaSThomas Richter return -EBUSY; 891a029a4eaSThomas Richter 892a029a4eaSThomas Richter cpumf_hw_inuse(); 893a029a4eaSThomas Richter file->private_data = NULL; 894a029a4eaSThomas Richter /* nonseekable_open() never fails */ 895a029a4eaSThomas Richter return nonseekable_open(inode, file); 896a029a4eaSThomas Richter } 897a029a4eaSThomas Richter 898a029a4eaSThomas Richter static int cfset_all_stop(void) 899a029a4eaSThomas Richter { 900a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p = { 901a029a4eaSThomas Richter .sets = cfset_request.ctrset, 902a029a4eaSThomas Richter }; 903a029a4eaSThomas Richter cpumask_var_t mask; 904a029a4eaSThomas Richter 905a029a4eaSThomas Richter if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 906a029a4eaSThomas Richter return -ENOMEM; 907a029a4eaSThomas Richter cpumask_and(mask, &cfset_request.mask, cpu_online_mask); 908a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_ioctl_off, &p, 1); 909a029a4eaSThomas Richter free_cpumask_var(mask); 910a029a4eaSThomas Richter return 0; 911a029a4eaSThomas Richter } 912a029a4eaSThomas Richter 913a029a4eaSThomas Richter static int cfset_all_start(void) 914a029a4eaSThomas Richter { 915a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p = { 916a029a4eaSThomas Richter .sets = cfset_request.ctrset, 917a029a4eaSThomas Richter .cpus_ack = ATOMIC_INIT(0), 918a029a4eaSThomas Richter }; 919a029a4eaSThomas Richter cpumask_var_t mask; 920a029a4eaSThomas Richter int rc = 0; 921a029a4eaSThomas Richter 922a029a4eaSThomas Richter if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 923a029a4eaSThomas Richter return -ENOMEM; 924a029a4eaSThomas Richter cpumask_and(mask, &cfset_request.mask, cpu_online_mask); 925a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_ioctl_on, &p, 1); 926a029a4eaSThomas Richter if (atomic_read(&p.cpus_ack) != cpumask_weight(mask)) { 927a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_ioctl_off, &p, 1); 928a029a4eaSThomas Richter rc = -EIO; 929a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s CPUs missing", __func__); 930a029a4eaSThomas Richter } 931a029a4eaSThomas Richter free_cpumask_var(mask); 932a029a4eaSThomas Richter return rc; 933a029a4eaSThomas Richter } 934a029a4eaSThomas Richter 935a029a4eaSThomas Richter 936a029a4eaSThomas Richter /* Return the maximum required space for all possible CPUs in case one 937a029a4eaSThomas Richter * CPU will be onlined during the START, READ, STOP cycles. 938a029a4eaSThomas Richter * To find out the size of the counter sets, any one CPU will do. They 939a029a4eaSThomas Richter * all have the same counter sets. 940a029a4eaSThomas Richter */ 941a029a4eaSThomas Richter static size_t cfset_needspace(unsigned int sets) 942a029a4eaSThomas Richter { 943a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = get_cpu_ptr(&cpu_cf_events); 944a029a4eaSThomas Richter size_t bytes = 0; 945a029a4eaSThomas Richter int i; 946a029a4eaSThomas Richter 947a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 948a029a4eaSThomas Richter if (!(sets & cpumf_ctr_ctl[i])) 949a029a4eaSThomas Richter continue; 950a029a4eaSThomas Richter bytes += cpum_cf_ctrset_size(i, &cpuhw->info) * sizeof(u64) + 951a029a4eaSThomas Richter sizeof(((struct s390_ctrset_setdata *)0)->set) + 952a029a4eaSThomas Richter sizeof(((struct s390_ctrset_setdata *)0)->no_cnts); 953a029a4eaSThomas Richter } 954a029a4eaSThomas Richter bytes = sizeof(((struct s390_ctrset_read *)0)->no_cpus) + nr_cpu_ids * 955a029a4eaSThomas Richter (bytes + sizeof(((struct s390_ctrset_cpudata *)0)->cpu_nr) + 956a029a4eaSThomas Richter sizeof(((struct s390_ctrset_cpudata *)0)->no_sets)); 957a029a4eaSThomas Richter put_cpu_ptr(&cpu_cf_events); 958a029a4eaSThomas Richter return bytes; 959a029a4eaSThomas Richter } 960a029a4eaSThomas Richter 961a029a4eaSThomas Richter static int cfset_all_copy(unsigned long arg, cpumask_t *mask) 962a029a4eaSThomas Richter { 963a029a4eaSThomas Richter struct s390_ctrset_read __user *ctrset_read; 964a029a4eaSThomas Richter unsigned int cpu, cpus, rc; 965a029a4eaSThomas Richter void __user *uptr; 966a029a4eaSThomas Richter 967a029a4eaSThomas Richter ctrset_read = (struct s390_ctrset_read __user *)arg; 968a029a4eaSThomas Richter uptr = ctrset_read->data; 969a029a4eaSThomas Richter for_each_cpu(cpu, mask) { 970a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = per_cpu_ptr(&cpu_cf_events, cpu); 971a029a4eaSThomas Richter struct s390_ctrset_cpudata __user *ctrset_cpudata; 972a029a4eaSThomas Richter 973a029a4eaSThomas Richter ctrset_cpudata = uptr; 974a029a4eaSThomas Richter rc = put_user(cpu, &ctrset_cpudata->cpu_nr); 975a029a4eaSThomas Richter rc |= put_user(cpuhw->sets, &ctrset_cpudata->no_sets); 976a029a4eaSThomas Richter rc |= copy_to_user(ctrset_cpudata->data, cpuhw->data, 977a029a4eaSThomas Richter cpuhw->used); 978a029a4eaSThomas Richter if (rc) 979a029a4eaSThomas Richter return -EFAULT; 980a029a4eaSThomas Richter uptr += sizeof(struct s390_ctrset_cpudata) + cpuhw->used; 981a029a4eaSThomas Richter cond_resched(); 982a029a4eaSThomas Richter } 983a029a4eaSThomas Richter cpus = cpumask_weight(mask); 984a029a4eaSThomas Richter if (put_user(cpus, &ctrset_read->no_cpus)) 985a029a4eaSThomas Richter return -EFAULT; 986a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s copied %ld\n", __func__, 987a029a4eaSThomas Richter uptr - (void __user *)ctrset_read->data); 988a029a4eaSThomas Richter return 0; 989a029a4eaSThomas Richter } 990a029a4eaSThomas Richter 991a029a4eaSThomas Richter static size_t cfset_cpuset_read(struct s390_ctrset_setdata *p, int ctrset, 992a029a4eaSThomas Richter int ctrset_size, size_t room) 993a029a4eaSThomas Richter { 994a029a4eaSThomas Richter size_t need = 0; 995a029a4eaSThomas Richter int rc = -1; 996a029a4eaSThomas Richter 997a029a4eaSThomas Richter need = sizeof(*p) + sizeof(u64) * ctrset_size; 998a029a4eaSThomas Richter if (need <= room) { 999a029a4eaSThomas Richter p->set = cpumf_ctr_ctl[ctrset]; 1000a029a4eaSThomas Richter p->no_cnts = ctrset_size; 1001a029a4eaSThomas Richter rc = ctr_stcctm(ctrset, ctrset_size, (u64 *)p->cv); 1002a029a4eaSThomas Richter if (rc == 3) /* Nothing stored */ 1003a029a4eaSThomas Richter need = 0; 1004a029a4eaSThomas Richter } 1005a029a4eaSThomas Richter return need; 1006a029a4eaSThomas Richter } 1007a029a4eaSThomas Richter 1008a029a4eaSThomas Richter /* Read all counter sets. */ 1009a029a4eaSThomas Richter static void cfset_cpu_read(void *parm) 1010a029a4eaSThomas Richter { 1011a029a4eaSThomas Richter struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); 1012a029a4eaSThomas Richter struct cfset_call_on_cpu_parm *p = parm; 1013a029a4eaSThomas Richter int set, set_size; 1014a029a4eaSThomas Richter size_t space; 1015a029a4eaSThomas Richter 1016a029a4eaSThomas Richter /* No data saved yet */ 1017a029a4eaSThomas Richter cpuhw->used = 0; 1018a029a4eaSThomas Richter cpuhw->sets = 0; 1019a029a4eaSThomas Richter memset(cpuhw->data, 0, sizeof(cpuhw->data)); 1020a029a4eaSThomas Richter 1021a029a4eaSThomas Richter /* Scan the counter sets */ 1022a029a4eaSThomas Richter for (set = CPUMF_CTR_SET_BASIC; set < CPUMF_CTR_SET_MAX; ++set) { 1023a029a4eaSThomas Richter struct s390_ctrset_setdata *sp = (void *)cpuhw->data + 1024a029a4eaSThomas Richter cpuhw->used; 1025a029a4eaSThomas Richter 1026a029a4eaSThomas Richter if (!(p->sets & cpumf_ctr_ctl[set])) 1027a029a4eaSThomas Richter continue; /* Counter set not in list */ 1028a029a4eaSThomas Richter set_size = cpum_cf_ctrset_size(set, &cpuhw->info); 1029a029a4eaSThomas Richter space = sizeof(cpuhw->data) - cpuhw->used; 1030a029a4eaSThomas Richter space = cfset_cpuset_read(sp, set, set_size, space); 1031a029a4eaSThomas Richter if (space) { 1032a029a4eaSThomas Richter cpuhw->used += space; 1033a029a4eaSThomas Richter cpuhw->sets += 1; 1034a029a4eaSThomas Richter } 1035a029a4eaSThomas Richter } 1036a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s sets %d used %zd\n", __func__, 1037a029a4eaSThomas Richter cpuhw->sets, cpuhw->used); 1038a029a4eaSThomas Richter } 1039a029a4eaSThomas Richter 1040a029a4eaSThomas Richter static int cfset_all_read(unsigned long arg) 1041a029a4eaSThomas Richter { 1042a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 1043a029a4eaSThomas Richter cpumask_var_t mask; 1044a029a4eaSThomas Richter int rc; 1045a029a4eaSThomas Richter 1046a029a4eaSThomas Richter if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 1047a029a4eaSThomas Richter return -ENOMEM; 1048a029a4eaSThomas Richter 1049a029a4eaSThomas Richter p.sets = cfset_request.ctrset; 1050a029a4eaSThomas Richter cpumask_and(mask, &cfset_request.mask, cpu_online_mask); 1051a029a4eaSThomas Richter on_each_cpu_mask(mask, cfset_cpu_read, &p, 1); 1052a029a4eaSThomas Richter rc = cfset_all_copy(arg, mask); 1053a029a4eaSThomas Richter free_cpumask_var(mask); 1054a029a4eaSThomas Richter return rc; 1055a029a4eaSThomas Richter } 1056a029a4eaSThomas Richter 1057a029a4eaSThomas Richter static long cfset_ioctl_read(unsigned long arg) 1058a029a4eaSThomas Richter { 1059a029a4eaSThomas Richter struct s390_ctrset_read read; 1060a029a4eaSThomas Richter int ret = 0; 1061a029a4eaSThomas Richter 1062a029a4eaSThomas Richter if (copy_from_user(&read, (char __user *)arg, sizeof(read))) 1063a029a4eaSThomas Richter return -EFAULT; 1064a029a4eaSThomas Richter ret = cfset_all_read(arg); 1065a029a4eaSThomas Richter return ret; 1066a029a4eaSThomas Richter } 1067a029a4eaSThomas Richter 1068a029a4eaSThomas Richter static long cfset_ioctl_stop(void) 1069a029a4eaSThomas Richter { 1070a029a4eaSThomas Richter int ret = ENXIO; 1071a029a4eaSThomas Richter 1072a029a4eaSThomas Richter if (cfset_request.ctrset) { 1073a029a4eaSThomas Richter ret = cfset_all_stop(); 1074a029a4eaSThomas Richter cfset_ctrset_clear(); 1075a029a4eaSThomas Richter } 1076a029a4eaSThomas Richter return ret; 1077a029a4eaSThomas Richter } 1078a029a4eaSThomas Richter 1079a029a4eaSThomas Richter static long cfset_ioctl_start(unsigned long arg) 1080a029a4eaSThomas Richter { 1081a029a4eaSThomas Richter struct s390_ctrset_start __user *ustart; 1082a029a4eaSThomas Richter struct s390_ctrset_start start; 1083a029a4eaSThomas Richter void __user *umask; 1084a029a4eaSThomas Richter unsigned int len; 1085a029a4eaSThomas Richter int ret = 0; 1086a029a4eaSThomas Richter size_t need; 1087a029a4eaSThomas Richter 1088a029a4eaSThomas Richter if (cfset_request.ctrset) 1089a029a4eaSThomas Richter return -EBUSY; 1090a029a4eaSThomas Richter ustart = (struct s390_ctrset_start __user *)arg; 1091a029a4eaSThomas Richter if (copy_from_user(&start, ustart, sizeof(start))) 1092a029a4eaSThomas Richter return -EFAULT; 1093a029a4eaSThomas Richter if (start.version != S390_HWCTR_START_VERSION) 1094a029a4eaSThomas Richter return -EINVAL; 1095a029a4eaSThomas Richter if (start.counter_sets & ~(cpumf_ctr_ctl[CPUMF_CTR_SET_BASIC] | 1096a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_USER] | 1097a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_CRYPTO] | 1098a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_EXT] | 1099a029a4eaSThomas Richter cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG])) 1100a029a4eaSThomas Richter return -EINVAL; /* Invalid counter set */ 1101a029a4eaSThomas Richter if (!start.counter_sets) 1102a029a4eaSThomas Richter return -EINVAL; /* No counter set at all? */ 1103a029a4eaSThomas Richter cpumask_clear(&cfset_request.mask); 1104a029a4eaSThomas Richter len = min_t(u64, start.cpumask_len, cpumask_size()); 1105a029a4eaSThomas Richter umask = (void __user *)start.cpumask; 1106a029a4eaSThomas Richter if (copy_from_user(&cfset_request.mask, umask, len)) 1107a029a4eaSThomas Richter return -EFAULT; 1108a029a4eaSThomas Richter if (cpumask_empty(&cfset_request.mask)) 1109a029a4eaSThomas Richter return -EINVAL; 1110a029a4eaSThomas Richter need = cfset_needspace(start.counter_sets); 1111a029a4eaSThomas Richter if (put_user(need, &ustart->data_bytes)) 1112a029a4eaSThomas Richter ret = -EFAULT; 1113a029a4eaSThomas Richter if (ret) 1114a029a4eaSThomas Richter goto out; 1115a029a4eaSThomas Richter cfset_request.ctrset = start.counter_sets; 1116a029a4eaSThomas Richter ret = cfset_all_start(); 1117a029a4eaSThomas Richter out: 1118a029a4eaSThomas Richter if (ret) 1119a029a4eaSThomas Richter cfset_ctrset_clear(); 1120a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 4, "%s sets %#lx need %ld ret %d\n", 1121a029a4eaSThomas Richter __func__, cfset_request.ctrset, need, ret); 1122a029a4eaSThomas Richter return ret; 1123a029a4eaSThomas Richter } 1124a029a4eaSThomas Richter 1125a029a4eaSThomas Richter /* Entry point to the /dev/hwctr device interface. 1126a029a4eaSThomas Richter * The ioctl system call supports three subcommands: 1127a029a4eaSThomas Richter * S390_HWCTR_START: Start the specified counter sets on a CPU list. The 1128a029a4eaSThomas Richter * counter set keeps running until explicitly stopped. Returns the number 1129a029a4eaSThomas Richter * of bytes needed to store the counter values. If another S390_HWCTR_START 1130a029a4eaSThomas Richter * ioctl subcommand is called without a previous S390_HWCTR_STOP stop 1131a029a4eaSThomas Richter * command, -EBUSY is returned. 1132a029a4eaSThomas Richter * S390_HWCTR_READ: Read the counter set values from specified CPU list given 1133a029a4eaSThomas Richter * with the S390_HWCTR_START command. 1134a029a4eaSThomas Richter * S390_HWCTR_STOP: Stops the counter sets on the CPU list given with the 1135a029a4eaSThomas Richter * previous S390_HWCTR_START subcommand. 1136a029a4eaSThomas Richter */ 1137a029a4eaSThomas Richter static long cfset_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1138a029a4eaSThomas Richter { 1139a029a4eaSThomas Richter int ret; 1140a029a4eaSThomas Richter 1141*a73de293SSebastian Andrzej Siewior cpus_read_lock(); 1142a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 1143a029a4eaSThomas Richter switch (cmd) { 1144a029a4eaSThomas Richter case S390_HWCTR_START: 1145a029a4eaSThomas Richter ret = cfset_ioctl_start(arg); 1146a029a4eaSThomas Richter break; 1147a029a4eaSThomas Richter case S390_HWCTR_STOP: 1148a029a4eaSThomas Richter ret = cfset_ioctl_stop(); 1149a029a4eaSThomas Richter break; 1150a029a4eaSThomas Richter case S390_HWCTR_READ: 1151a029a4eaSThomas Richter ret = cfset_ioctl_read(arg); 1152a029a4eaSThomas Richter break; 1153a029a4eaSThomas Richter default: 1154a029a4eaSThomas Richter ret = -ENOTTY; 1155a029a4eaSThomas Richter break; 1156a029a4eaSThomas Richter } 1157a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1158*a73de293SSebastian Andrzej Siewior cpus_read_unlock(); 1159a029a4eaSThomas Richter return ret; 1160a029a4eaSThomas Richter } 1161a029a4eaSThomas Richter 1162a029a4eaSThomas Richter static const struct file_operations cfset_fops = { 1163a029a4eaSThomas Richter .owner = THIS_MODULE, 1164a029a4eaSThomas Richter .open = cfset_open, 1165a029a4eaSThomas Richter .release = cfset_release, 1166a029a4eaSThomas Richter .unlocked_ioctl = cfset_ioctl, 1167a029a4eaSThomas Richter .compat_ioctl = cfset_ioctl, 1168a029a4eaSThomas Richter .llseek = no_llseek 1169a029a4eaSThomas Richter }; 1170a029a4eaSThomas Richter 1171a029a4eaSThomas Richter static struct miscdevice cfset_dev = { 1172a029a4eaSThomas Richter .name = S390_HWCTR_DEVICE, 1173a029a4eaSThomas Richter .minor = MISC_DYNAMIC_MINOR, 1174a029a4eaSThomas Richter .fops = &cfset_fops, 1175a029a4eaSThomas Richter }; 1176a029a4eaSThomas Richter 1177a029a4eaSThomas Richter int cfset_online_cpu(unsigned int cpu) 1178a029a4eaSThomas Richter { 1179a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 1180a029a4eaSThomas Richter 1181a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 1182a029a4eaSThomas Richter if (cfset_request.ctrset) { 1183a029a4eaSThomas Richter p.sets = cfset_request.ctrset; 1184a029a4eaSThomas Richter cfset_ioctl_on(&p); 1185a029a4eaSThomas Richter cpumask_set_cpu(cpu, &cfset_request.mask); 1186a029a4eaSThomas Richter } 1187a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1188a029a4eaSThomas Richter return 0; 1189a029a4eaSThomas Richter } 1190a029a4eaSThomas Richter 1191a029a4eaSThomas Richter int cfset_offline_cpu(unsigned int cpu) 1192a029a4eaSThomas Richter { 1193a029a4eaSThomas Richter struct cfset_call_on_cpu_parm p; 1194a029a4eaSThomas Richter 1195a029a4eaSThomas Richter mutex_lock(&cfset_ctrset_mutex); 1196a029a4eaSThomas Richter if (cfset_request.ctrset) { 1197a029a4eaSThomas Richter p.sets = cfset_request.ctrset; 1198a029a4eaSThomas Richter cfset_ioctl_off(&p); 1199a029a4eaSThomas Richter cpumask_clear_cpu(cpu, &cfset_request.mask); 1200a029a4eaSThomas Richter } 1201a029a4eaSThomas Richter mutex_unlock(&cfset_ctrset_mutex); 1202a029a4eaSThomas Richter return 0; 1203a029a4eaSThomas Richter } 1204a029a4eaSThomas Richter 1205a029a4eaSThomas Richter static void cfdiag_read(struct perf_event *event) 1206a029a4eaSThomas Richter { 1207a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 3, "%s event %#llx count %ld\n", __func__, 1208a029a4eaSThomas Richter event->attr.config, local64_read(&event->count)); 1209a029a4eaSThomas Richter } 1210a029a4eaSThomas Richter 1211a029a4eaSThomas Richter static int get_authctrsets(void) 1212a029a4eaSThomas Richter { 1213a029a4eaSThomas Richter struct cpu_cf_events *cpuhw; 1214a029a4eaSThomas Richter unsigned long auth = 0; 1215a029a4eaSThomas Richter enum cpumf_ctr_set i; 1216a029a4eaSThomas Richter 1217a029a4eaSThomas Richter cpuhw = &get_cpu_var(cpu_cf_events); 1218a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 1219a029a4eaSThomas Richter if (cpuhw->info.auth_ctl & cpumf_ctr_ctl[i]) 1220a029a4eaSThomas Richter auth |= cpumf_ctr_ctl[i]; 1221a029a4eaSThomas Richter } 1222a029a4eaSThomas Richter put_cpu_var(cpu_cf_events); 1223a029a4eaSThomas Richter return auth; 1224a029a4eaSThomas Richter } 1225a029a4eaSThomas Richter 1226a029a4eaSThomas Richter /* Setup the event. Test for authorized counter sets and only include counter 1227a029a4eaSThomas Richter * sets which are authorized at the time of the setup. Including unauthorized 1228a029a4eaSThomas Richter * counter sets result in specification exception (and panic). 1229a029a4eaSThomas Richter */ 1230a029a4eaSThomas Richter static int cfdiag_event_init2(struct perf_event *event) 1231a029a4eaSThomas Richter { 1232a029a4eaSThomas Richter struct perf_event_attr *attr = &event->attr; 1233a029a4eaSThomas Richter int err = 0; 1234a029a4eaSThomas Richter 1235a029a4eaSThomas Richter /* Set sample_period to indicate sampling */ 1236a029a4eaSThomas Richter event->hw.config = attr->config; 1237a029a4eaSThomas Richter event->hw.sample_period = attr->sample_period; 1238a029a4eaSThomas Richter local64_set(&event->hw.period_left, event->hw.sample_period); 1239a029a4eaSThomas Richter local64_set(&event->count, 0); 1240a029a4eaSThomas Richter event->hw.last_period = event->hw.sample_period; 1241a029a4eaSThomas Richter 1242a029a4eaSThomas Richter /* Add all authorized counter sets to config_base. The 1243a029a4eaSThomas Richter * the hardware init function is either called per-cpu or just once 1244a029a4eaSThomas Richter * for all CPUS (event->cpu == -1). This depends on the whether 1245a029a4eaSThomas Richter * counting is started for all CPUs or on a per workload base where 1246a029a4eaSThomas Richter * the perf event moves from one CPU to another CPU. 1247a029a4eaSThomas Richter * Checking the authorization on any CPU is fine as the hardware 1248a029a4eaSThomas Richter * applies the same authorization settings to all CPUs. 1249a029a4eaSThomas Richter */ 1250a029a4eaSThomas Richter event->hw.config_base = get_authctrsets(); 1251a029a4eaSThomas Richter 1252a029a4eaSThomas Richter /* No authorized counter sets, nothing to count/sample */ 1253a029a4eaSThomas Richter if (!event->hw.config_base) 1254a029a4eaSThomas Richter err = -EINVAL; 1255a029a4eaSThomas Richter 1256a029a4eaSThomas Richter debug_sprintf_event(cf_dbg, 5, "%s err %d config_base %#lx\n", 1257a029a4eaSThomas Richter __func__, err, event->hw.config_base); 1258a029a4eaSThomas Richter return err; 1259a029a4eaSThomas Richter } 1260a029a4eaSThomas Richter 1261a029a4eaSThomas Richter static int cfdiag_event_init(struct perf_event *event) 1262a029a4eaSThomas Richter { 1263a029a4eaSThomas Richter struct perf_event_attr *attr = &event->attr; 1264a029a4eaSThomas Richter int err = -ENOENT; 1265a029a4eaSThomas Richter 1266a029a4eaSThomas Richter if (event->attr.config != PERF_EVENT_CPUM_CF_DIAG || 1267a029a4eaSThomas Richter event->attr.type != event->pmu->type) 1268a029a4eaSThomas Richter goto out; 1269a029a4eaSThomas Richter 1270a029a4eaSThomas Richter /* Raw events are used to access counters directly, 1271a029a4eaSThomas Richter * hence do not permit excludes. 1272a029a4eaSThomas Richter * This event is useless without PERF_SAMPLE_RAW to return counter set 1273a029a4eaSThomas Richter * values as raw data. 1274a029a4eaSThomas Richter */ 1275a029a4eaSThomas Richter if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv || 1276a029a4eaSThomas Richter !(attr->sample_type & (PERF_SAMPLE_CPU | PERF_SAMPLE_RAW))) { 1277a029a4eaSThomas Richter err = -EOPNOTSUPP; 1278a029a4eaSThomas Richter goto out; 1279a029a4eaSThomas Richter } 1280a029a4eaSThomas Richter 1281a029a4eaSThomas Richter /* Initialize for using the CPU-measurement counter facility */ 1282a029a4eaSThomas Richter cpumf_hw_inuse(); 1283a029a4eaSThomas Richter event->destroy = hw_perf_event_destroy; 1284a029a4eaSThomas Richter 1285a029a4eaSThomas Richter err = cfdiag_event_init2(event); 1286a029a4eaSThomas Richter if (unlikely(err)) 1287a029a4eaSThomas Richter event->destroy(event); 1288a029a4eaSThomas Richter out: 1289a029a4eaSThomas Richter return err; 1290a029a4eaSThomas Richter } 1291a029a4eaSThomas Richter 1292a029a4eaSThomas Richter /* Create cf_diag/events/CF_DIAG event sysfs file. This counter is used 1293a029a4eaSThomas Richter * to collect the complete counter sets for a scheduled process. Target 1294a029a4eaSThomas Richter * are complete counter sets attached as raw data to the artificial event. 1295a029a4eaSThomas Richter * This results in complete counter sets available when a process is 1296a029a4eaSThomas Richter * scheduled. Contains the delta of every counter while the process was 1297a029a4eaSThomas Richter * running. 1298a029a4eaSThomas Richter */ 1299a029a4eaSThomas Richter CPUMF_EVENT_ATTR(CF_DIAG, CF_DIAG, PERF_EVENT_CPUM_CF_DIAG); 1300a029a4eaSThomas Richter 1301a029a4eaSThomas Richter static struct attribute *cfdiag_events_attr[] = { 1302a029a4eaSThomas Richter CPUMF_EVENT_PTR(CF_DIAG, CF_DIAG), 1303a029a4eaSThomas Richter NULL, 1304a029a4eaSThomas Richter }; 1305a029a4eaSThomas Richter 1306a029a4eaSThomas Richter PMU_FORMAT_ATTR(event, "config:0-63"); 1307a029a4eaSThomas Richter 1308a029a4eaSThomas Richter static struct attribute *cfdiag_format_attr[] = { 1309a029a4eaSThomas Richter &format_attr_event.attr, 1310a029a4eaSThomas Richter NULL, 1311a029a4eaSThomas Richter }; 1312a029a4eaSThomas Richter 1313a029a4eaSThomas Richter static struct attribute_group cfdiag_events_group = { 1314a029a4eaSThomas Richter .name = "events", 1315a029a4eaSThomas Richter .attrs = cfdiag_events_attr, 1316a029a4eaSThomas Richter }; 1317a029a4eaSThomas Richter static struct attribute_group cfdiag_format_group = { 1318a029a4eaSThomas Richter .name = "format", 1319a029a4eaSThomas Richter .attrs = cfdiag_format_attr, 1320a029a4eaSThomas Richter }; 1321a029a4eaSThomas Richter static const struct attribute_group *cfdiag_attr_groups[] = { 1322a029a4eaSThomas Richter &cfdiag_events_group, 1323a029a4eaSThomas Richter &cfdiag_format_group, 1324a029a4eaSThomas Richter NULL, 1325a029a4eaSThomas Richter }; 1326a029a4eaSThomas Richter 1327a029a4eaSThomas Richter /* Performance monitoring unit for event CF_DIAG. Since this event 1328a029a4eaSThomas Richter * is also started and stopped via the perf_event_open() system call, use 1329a029a4eaSThomas Richter * the same event enable/disable call back functions. They do not 1330a029a4eaSThomas Richter * have a pointer to the perf_event strcture as first parameter. 1331a029a4eaSThomas Richter * 1332a029a4eaSThomas Richter * The functions XXX_add, XXX_del, XXX_start and XXX_stop are also common. 1333a029a4eaSThomas Richter * Reuse them and distinguish the event (always first parameter) via 1334a029a4eaSThomas Richter * 'config' member. 1335a029a4eaSThomas Richter */ 1336a029a4eaSThomas Richter static struct pmu cf_diag = { 1337a029a4eaSThomas Richter .task_ctx_nr = perf_sw_context, 1338a029a4eaSThomas Richter .event_init = cfdiag_event_init, 1339a029a4eaSThomas Richter .pmu_enable = cpumf_pmu_enable, 1340a029a4eaSThomas Richter .pmu_disable = cpumf_pmu_disable, 1341a029a4eaSThomas Richter .add = cpumf_pmu_add, 1342a029a4eaSThomas Richter .del = cpumf_pmu_del, 1343a029a4eaSThomas Richter .start = cpumf_pmu_start, 1344a029a4eaSThomas Richter .stop = cpumf_pmu_stop, 1345a029a4eaSThomas Richter .read = cfdiag_read, 1346a029a4eaSThomas Richter 1347a029a4eaSThomas Richter .attr_groups = cfdiag_attr_groups 1348a029a4eaSThomas Richter }; 1349a029a4eaSThomas Richter 1350a029a4eaSThomas Richter /* Calculate memory needed to store all counter sets together with header and 1351a029a4eaSThomas Richter * trailer data. This is independent of the counter set authorization which 1352a029a4eaSThomas Richter * can vary depending on the configuration. 1353a029a4eaSThomas Richter */ 1354a029a4eaSThomas Richter static size_t cfdiag_maxsize(struct cpumf_ctr_info *info) 1355a029a4eaSThomas Richter { 1356a029a4eaSThomas Richter size_t max_size = sizeof(struct cf_trailer_entry); 1357a029a4eaSThomas Richter enum cpumf_ctr_set i; 1358a029a4eaSThomas Richter 1359a029a4eaSThomas Richter for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { 1360a029a4eaSThomas Richter size_t size = cpum_cf_ctrset_size(i, info); 1361a029a4eaSThomas Richter 1362a029a4eaSThomas Richter if (size) 1363a029a4eaSThomas Richter max_size += size * sizeof(u64) + 1364a029a4eaSThomas Richter sizeof(struct cf_ctrset_entry); 1365a029a4eaSThomas Richter } 1366a029a4eaSThomas Richter return max_size; 1367a029a4eaSThomas Richter } 1368a029a4eaSThomas Richter 1369a029a4eaSThomas Richter /* Get the CPU speed, try sampling facility first and CPU attributes second. */ 1370a029a4eaSThomas Richter static void cfdiag_get_cpu_speed(void) 1371a029a4eaSThomas Richter { 1372a029a4eaSThomas Richter if (cpum_sf_avail()) { /* Sampling facility first */ 1373a029a4eaSThomas Richter struct hws_qsi_info_block si; 1374a029a4eaSThomas Richter 1375a029a4eaSThomas Richter memset(&si, 0, sizeof(si)); 1376a029a4eaSThomas Richter if (!qsi(&si)) { 1377a029a4eaSThomas Richter cfdiag_cpu_speed = si.cpu_speed; 1378a029a4eaSThomas Richter return; 1379a029a4eaSThomas Richter } 1380a029a4eaSThomas Richter } 1381a029a4eaSThomas Richter 1382a029a4eaSThomas Richter /* Fallback: CPU speed extract static part. Used in case 1383a029a4eaSThomas Richter * CPU Measurement Sampling Facility is turned off. 1384a029a4eaSThomas Richter */ 1385a029a4eaSThomas Richter if (test_facility(34)) { 1386a029a4eaSThomas Richter unsigned long mhz = __ecag(ECAG_CPU_ATTRIBUTE, 0); 1387a029a4eaSThomas Richter 1388a029a4eaSThomas Richter if (mhz != -1UL) 1389a029a4eaSThomas Richter cfdiag_cpu_speed = mhz & 0xffffffff; 1390a029a4eaSThomas Richter } 1391a029a4eaSThomas Richter } 1392a029a4eaSThomas Richter 1393a029a4eaSThomas Richter static int cfset_init(void) 1394a029a4eaSThomas Richter { 1395a029a4eaSThomas Richter struct cpumf_ctr_info info; 1396a029a4eaSThomas Richter size_t need; 1397a029a4eaSThomas Richter int rc; 1398a029a4eaSThomas Richter 1399a029a4eaSThomas Richter if (qctri(&info)) 1400a029a4eaSThomas Richter return -ENODEV; 1401a029a4eaSThomas Richter 1402a029a4eaSThomas Richter cfdiag_get_cpu_speed(); 1403a029a4eaSThomas Richter /* Make sure the counter set data fits into predefined buffer. */ 1404a029a4eaSThomas Richter need = cfdiag_maxsize(&info); 1405a029a4eaSThomas Richter if (need > sizeof(((struct cpu_cf_events *)0)->start)) { 1406a029a4eaSThomas Richter pr_err("Insufficient memory for PMU(cpum_cf_diag) need=%zu\n", 1407a029a4eaSThomas Richter need); 1408a029a4eaSThomas Richter return -ENOMEM; 1409a029a4eaSThomas Richter } 1410a029a4eaSThomas Richter 1411a029a4eaSThomas Richter rc = misc_register(&cfset_dev); 1412a029a4eaSThomas Richter if (rc) { 1413a029a4eaSThomas Richter pr_err("Registration of /dev/%s failed rc=%i\n", 1414a029a4eaSThomas Richter cfset_dev.name, rc); 1415a029a4eaSThomas Richter goto out; 1416a029a4eaSThomas Richter } 1417a029a4eaSThomas Richter 1418a029a4eaSThomas Richter rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", -1); 1419a029a4eaSThomas Richter if (rc) { 1420a029a4eaSThomas Richter misc_deregister(&cfset_dev); 1421a029a4eaSThomas Richter pr_err("Registration of PMU(cpum_cf_diag) failed with rc=%i\n", 1422a029a4eaSThomas Richter rc); 1423a029a4eaSThomas Richter } 1424a029a4eaSThomas Richter out: 1425a029a4eaSThomas Richter return rc; 1426a029a4eaSThomas Richter } 1427a029a4eaSThomas Richter 1428a029a4eaSThomas Richter device_initcall(cpumf_pmu_init); 1429