perf_cpum_cf.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /*
  2. * Performance event support for s390x - CPU-measurement Counter Facility
  3. *
  4. * Copyright IBM Corp. 2012
  5. * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License (version 2 only)
  9. * as published by the Free Software Foundation.
  10. */
  11. #define KMSG_COMPONENT "cpum_cf"
  12. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  13. #include <linux/kernel.h>
  14. #include <linux/kernel_stat.h>
  15. #include <linux/perf_event.h>
  16. #include <linux/percpu.h>
  17. #include <linux/notifier.h>
  18. #include <linux/init.h>
  19. #include <linux/export.h>
  20. #include <asm/ctl_reg.h>
  21. #include <asm/irq.h>
  22. #include <asm/cpu_mf.h>
  23. /* CPU-measurement counter facility supports these CPU counter sets:
  24. * For CPU counter sets:
  25. * Basic counter set: 0-31
  26. * Problem-state counter set: 32-63
  27. * Crypto-activity counter set: 64-127
  28. * Extented counter set: 128-159
  29. */
  30. enum cpumf_ctr_set {
  31. /* CPU counter sets */
  32. CPUMF_CTR_SET_BASIC = 0,
  33. CPUMF_CTR_SET_USER = 1,
  34. CPUMF_CTR_SET_CRYPTO = 2,
  35. CPUMF_CTR_SET_EXT = 3,
  36. /* Maximum number of counter sets */
  37. CPUMF_CTR_SET_MAX,
  38. };
  39. #define CPUMF_LCCTL_ENABLE_SHIFT 16
  40. #define CPUMF_LCCTL_ACTCTL_SHIFT 0
  41. static const u64 cpumf_state_ctl[CPUMF_CTR_SET_MAX] = {
  42. [CPUMF_CTR_SET_BASIC] = 0x02,
  43. [CPUMF_CTR_SET_USER] = 0x04,
  44. [CPUMF_CTR_SET_CRYPTO] = 0x08,
  45. [CPUMF_CTR_SET_EXT] = 0x01,
  46. };
  47. static void ctr_set_enable(u64 *state, int ctr_set)
  48. {
  49. *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT;
  50. }
  51. static void ctr_set_disable(u64 *state, int ctr_set)
  52. {
  53. *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT);
  54. }
  55. static void ctr_set_start(u64 *state, int ctr_set)
  56. {
  57. *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT;
  58. }
  59. static void ctr_set_stop(u64 *state, int ctr_set)
  60. {
  61. *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT);
  62. }
  63. /* Local CPUMF event structure */
  64. struct cpu_hw_events {
  65. struct cpumf_ctr_info info;
  66. atomic_t ctr_set[CPUMF_CTR_SET_MAX];
  67. u64 state, tx_state;
  68. unsigned int flags;
  69. unsigned int txn_flags;
  70. };
  71. static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
  72. .ctr_set = {
  73. [CPUMF_CTR_SET_BASIC] = ATOMIC_INIT(0),
  74. [CPUMF_CTR_SET_USER] = ATOMIC_INIT(0),
  75. [CPUMF_CTR_SET_CRYPTO] = ATOMIC_INIT(0),
  76. [CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0),
  77. },
  78. .state = 0,
  79. .flags = 0,
  80. .txn_flags = 0,
  81. };
  82. static int get_counter_set(u64 event)
  83. {
  84. int set = -1;
  85. if (event < 32)
  86. set = CPUMF_CTR_SET_BASIC;
  87. else if (event < 64)
  88. set = CPUMF_CTR_SET_USER;
  89. else if (event < 128)
  90. set = CPUMF_CTR_SET_CRYPTO;
  91. else if (event < 256)
  92. set = CPUMF_CTR_SET_EXT;
  93. return set;
  94. }
  95. static int validate_event(const struct hw_perf_event *hwc)
  96. {
  97. switch (hwc->config_base) {
  98. case CPUMF_CTR_SET_BASIC:
  99. case CPUMF_CTR_SET_USER:
  100. case CPUMF_CTR_SET_CRYPTO:
  101. case CPUMF_CTR_SET_EXT:
  102. /* check for reserved counters */
  103. if ((hwc->config >= 6 && hwc->config <= 31) ||
  104. (hwc->config >= 38 && hwc->config <= 63) ||
  105. (hwc->config >= 80 && hwc->config <= 127))
  106. return -EOPNOTSUPP;
  107. break;
  108. default:
  109. return -EINVAL;
  110. }
  111. return 0;
  112. }
  113. static int validate_ctr_version(const struct hw_perf_event *hwc)
  114. {
  115. struct cpu_hw_events *cpuhw;
  116. int err = 0;
  117. cpuhw = &get_cpu_var(cpu_hw_events);
  118. /* check required version for counter sets */
  119. switch (hwc->config_base) {
  120. case CPUMF_CTR_SET_BASIC:
  121. case CPUMF_CTR_SET_USER:
  122. if (cpuhw->info.cfvn < 1)
  123. err = -EOPNOTSUPP;
  124. break;
  125. case CPUMF_CTR_SET_CRYPTO:
  126. case CPUMF_CTR_SET_EXT:
  127. if (cpuhw->info.csvn < 1)
  128. err = -EOPNOTSUPP;
  129. if ((cpuhw->info.csvn == 1 && hwc->config > 159) ||
  130. (cpuhw->info.csvn == 2 && hwc->config > 175) ||
  131. (cpuhw->info.csvn > 2 && hwc->config > 255))
  132. err = -EOPNOTSUPP;
  133. break;
  134. }
  135. put_cpu_var(cpu_hw_events);
  136. return err;
  137. }
  138. static int validate_ctr_auth(const struct hw_perf_event *hwc)
  139. {
  140. struct cpu_hw_events *cpuhw;
  141. u64 ctrs_state;
  142. int err = 0;
  143. cpuhw = &get_cpu_var(cpu_hw_events);
  144. /* Check authorization for cpu counter sets.
  145. * If the particular CPU counter set is not authorized,
  146. * return with -ENOENT in order to fall back to other
  147. * PMUs that might suffice the event request.
  148. */
  149. ctrs_state = cpumf_state_ctl[hwc->config_base];
  150. if (!(ctrs_state & cpuhw->info.auth_ctl))
  151. err = -ENOENT;
  152. put_cpu_var(cpu_hw_events);
  153. return err;
  154. }
  155. /*
  156. * Change the CPUMF state to active.
  157. * Enable and activate the CPU-counter sets according
  158. * to the per-cpu control state.
  159. */
  160. static void cpumf_pmu_enable(struct pmu *pmu)
  161. {
  162. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  163. int err;
  164. if (cpuhw->flags & PMU_F_ENABLED)
  165. return;
  166. err = lcctl(cpuhw->state);
  167. if (err) {
  168. pr_err("Enabling the performance measuring unit "
  169. "failed with rc=%x\n", err);
  170. return;
  171. }
  172. cpuhw->flags |= PMU_F_ENABLED;
  173. }
  174. /*
  175. * Change the CPUMF state to inactive.
  176. * Disable and enable (inactive) the CPU-counter sets according
  177. * to the per-cpu control state.
  178. */
  179. static void cpumf_pmu_disable(struct pmu *pmu)
  180. {
  181. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  182. int err;
  183. u64 inactive;
  184. if (!(cpuhw->flags & PMU_F_ENABLED))
  185. return;
  186. inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
  187. err = lcctl(inactive);
  188. if (err) {
  189. pr_err("Disabling the performance measuring unit "
  190. "failed with rc=%x\n", err);
  191. return;
  192. }
  193. cpuhw->flags &= ~PMU_F_ENABLED;
  194. }
  195. /* Number of perf events counting hardware events */
  196. static atomic_t num_events = ATOMIC_INIT(0);
  197. /* Used to avoid races in calling reserve/release_cpumf_hardware */
  198. static DEFINE_MUTEX(pmc_reserve_mutex);
  199. /* CPU-measurement alerts for the counter facility */
  200. static void cpumf_measurement_alert(struct ext_code ext_code,
  201. unsigned int alert, unsigned long unused)
  202. {
  203. struct cpu_hw_events *cpuhw;
  204. if (!(alert & CPU_MF_INT_CF_MASK))
  205. return;
  206. inc_irq_stat(IRQEXT_CMC);
  207. cpuhw = this_cpu_ptr(&cpu_hw_events);
  208. /* Measurement alerts are shared and might happen when the PMU
  209. * is not reserved. Ignore these alerts in this case. */
  210. if (!(cpuhw->flags & PMU_F_RESERVED))
  211. return;
  212. /* counter authorization change alert */
  213. if (alert & CPU_MF_INT_CF_CACA)
  214. qctri(&cpuhw->info);
  215. /* loss of counter data alert */
  216. if (alert & CPU_MF_INT_CF_LCDA)
  217. pr_err("CPU[%i] Counter data was lost\n", smp_processor_id());
  218. }
  219. #define PMC_INIT 0
  220. #define PMC_RELEASE 1
  221. static void setup_pmc_cpu(void *flags)
  222. {
  223. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  224. switch (*((int *) flags)) {
  225. case PMC_INIT:
  226. memset(&cpuhw->info, 0, sizeof(cpuhw->info));
  227. qctri(&cpuhw->info);
  228. cpuhw->flags |= PMU_F_RESERVED;
  229. break;
  230. case PMC_RELEASE:
  231. cpuhw->flags &= ~PMU_F_RESERVED;
  232. break;
  233. }
  234. /* Disable CPU counter sets */
  235. lcctl(0);
  236. }
  237. /* Initialize the CPU-measurement facility */
  238. static int reserve_pmc_hardware(void)
  239. {
  240. int flags = PMC_INIT;
  241. on_each_cpu(setup_pmc_cpu, &flags, 1);
  242. irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
  243. return 0;
  244. }
  245. /* Release the CPU-measurement facility */
  246. static void release_pmc_hardware(void)
  247. {
  248. int flags = PMC_RELEASE;
  249. on_each_cpu(setup_pmc_cpu, &flags, 1);
  250. irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
  251. }
  252. /* Release the PMU if event is the last perf event */
  253. static void hw_perf_event_destroy(struct perf_event *event)
  254. {
  255. if (!atomic_add_unless(&num_events, -1, 1)) {
  256. mutex_lock(&pmc_reserve_mutex);
  257. if (atomic_dec_return(&num_events) == 0)
  258. release_pmc_hardware();
  259. mutex_unlock(&pmc_reserve_mutex);
  260. }
  261. }
  262. /* CPUMF <-> perf event mappings for kernel+userspace (basic set) */
  263. static const int cpumf_generic_events_basic[] = {
  264. [PERF_COUNT_HW_CPU_CYCLES] = 0,
  265. [PERF_COUNT_HW_INSTRUCTIONS] = 1,
  266. [PERF_COUNT_HW_CACHE_REFERENCES] = -1,
  267. [PERF_COUNT_HW_CACHE_MISSES] = -1,
  268. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
  269. [PERF_COUNT_HW_BRANCH_MISSES] = -1,
  270. [PERF_COUNT_HW_BUS_CYCLES] = -1,
  271. };
  272. /* CPUMF <-> perf event mappings for userspace (problem-state set) */
  273. static const int cpumf_generic_events_user[] = {
  274. [PERF_COUNT_HW_CPU_CYCLES] = 32,
  275. [PERF_COUNT_HW_INSTRUCTIONS] = 33,
  276. [PERF_COUNT_HW_CACHE_REFERENCES] = -1,
  277. [PERF_COUNT_HW_CACHE_MISSES] = -1,
  278. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
  279. [PERF_COUNT_HW_BRANCH_MISSES] = -1,
  280. [PERF_COUNT_HW_BUS_CYCLES] = -1,
  281. };
  282. static int __hw_perf_event_init(struct perf_event *event)
  283. {
  284. struct perf_event_attr *attr = &event->attr;
  285. struct hw_perf_event *hwc = &event->hw;
  286. int err;
  287. u64 ev;
  288. switch (attr->type) {
  289. case PERF_TYPE_RAW:
  290. /* Raw events are used to access counters directly,
  291. * hence do not permit excludes */
  292. if (attr->exclude_kernel || attr->exclude_user ||
  293. attr->exclude_hv)
  294. return -EOPNOTSUPP;
  295. ev = attr->config;
  296. break;
  297. case PERF_TYPE_HARDWARE:
  298. ev = attr->config;
  299. /* Count user space (problem-state) only */
  300. if (!attr->exclude_user && attr->exclude_kernel) {
  301. if (ev >= ARRAY_SIZE(cpumf_generic_events_user))
  302. return -EOPNOTSUPP;
  303. ev = cpumf_generic_events_user[ev];
  304. /* No support for kernel space counters only */
  305. } else if (!attr->exclude_kernel && attr->exclude_user) {
  306. return -EOPNOTSUPP;
  307. /* Count user and kernel space */
  308. } else {
  309. if (ev >= ARRAY_SIZE(cpumf_generic_events_basic))
  310. return -EOPNOTSUPP;
  311. ev = cpumf_generic_events_basic[ev];
  312. }
  313. break;
  314. default:
  315. return -ENOENT;
  316. }
  317. if (ev == -1)
  318. return -ENOENT;
  319. if (ev >= PERF_CPUM_CF_MAX_CTR)
  320. return -EINVAL;
  321. /* Use the hardware perf event structure to store the counter number
  322. * in 'config' member and the counter set to which the counter belongs
  323. * in the 'config_base'. The counter set (config_base) is then used
  324. * to enable/disable the counters.
  325. */
  326. hwc->config = ev;
  327. hwc->config_base = get_counter_set(ev);
  328. /* Validate the counter that is assigned to this event.
  329. * Because the counter facility can use numerous counters at the
  330. * same time without constraints, it is not necessary to explicitly
  331. * validate event groups (event->group_leader != event).
  332. */
  333. err = validate_event(hwc);
  334. if (err)
  335. return err;
  336. /* Initialize for using the CPU-measurement counter facility */
  337. if (!atomic_inc_not_zero(&num_events)) {
  338. mutex_lock(&pmc_reserve_mutex);
  339. if (atomic_read(&num_events) == 0 && reserve_pmc_hardware())
  340. err = -EBUSY;
  341. else
  342. atomic_inc(&num_events);
  343. mutex_unlock(&pmc_reserve_mutex);
  344. }
  345. event->destroy = hw_perf_event_destroy;
  346. /* Finally, validate version and authorization of the counter set */
  347. err = validate_ctr_auth(hwc);
  348. if (!err)
  349. err = validate_ctr_version(hwc);
  350. return err;
  351. }
  352. static int cpumf_pmu_event_init(struct perf_event *event)
  353. {
  354. int err;
  355. switch (event->attr.type) {
  356. case PERF_TYPE_HARDWARE:
  357. case PERF_TYPE_HW_CACHE:
  358. case PERF_TYPE_RAW:
  359. err = __hw_perf_event_init(event);
  360. break;
  361. default:
  362. return -ENOENT;
  363. }
  364. if (unlikely(err) && event->destroy)
  365. event->destroy(event);
  366. return err;
  367. }
  368. static int hw_perf_event_reset(struct perf_event *event)
  369. {
  370. u64 prev, new;
  371. int err;
  372. do {
  373. prev = local64_read(&event->hw.prev_count);
  374. err = ecctr(event->hw.config, &new);
  375. if (err) {
  376. if (err != 3)
  377. break;
  378. /* The counter is not (yet) available. This
  379. * might happen if the counter set to which
  380. * this counter belongs is in the disabled
  381. * state.
  382. */
  383. new = 0;
  384. }
  385. } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
  386. return err;
  387. }
  388. static int hw_perf_event_update(struct perf_event *event)
  389. {
  390. u64 prev, new, delta;
  391. int err;
  392. do {
  393. prev = local64_read(&event->hw.prev_count);
  394. err = ecctr(event->hw.config, &new);
  395. if (err)
  396. goto out;
  397. } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
  398. delta = (prev <= new) ? new - prev
  399. : (-1ULL - prev) + new + 1; /* overflow */
  400. local64_add(delta, &event->count);
  401. out:
  402. return err;
  403. }
  404. static void cpumf_pmu_read(struct perf_event *event)
  405. {
  406. if (event->hw.state & PERF_HES_STOPPED)
  407. return;
  408. hw_perf_event_update(event);
  409. }
  410. static void cpumf_pmu_start(struct perf_event *event, int flags)
  411. {
  412. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  413. struct hw_perf_event *hwc = &event->hw;
  414. if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
  415. return;
  416. if (WARN_ON_ONCE(hwc->config == -1))
  417. return;
  418. if (flags & PERF_EF_RELOAD)
  419. WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
  420. hwc->state = 0;
  421. /* (Re-)enable and activate the counter set */
  422. ctr_set_enable(&cpuhw->state, hwc->config_base);
  423. ctr_set_start(&cpuhw->state, hwc->config_base);
  424. /* The counter set to which this counter belongs can be already active.
  425. * Because all counters in a set are active, the event->hw.prev_count
  426. * needs to be synchronized. At this point, the counter set can be in
  427. * the inactive or disabled state.
  428. */
  429. hw_perf_event_reset(event);
  430. /* increment refcount for this counter set */
  431. atomic_inc(&cpuhw->ctr_set[hwc->config_base]);
  432. }
  433. static void cpumf_pmu_stop(struct perf_event *event, int flags)
  434. {
  435. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  436. struct hw_perf_event *hwc = &event->hw;
  437. if (!(hwc->state & PERF_HES_STOPPED)) {
  438. /* Decrement reference count for this counter set and if this
  439. * is the last used counter in the set, clear activation
  440. * control and set the counter set state to inactive.
  441. */
  442. if (!atomic_dec_return(&cpuhw->ctr_set[hwc->config_base]))
  443. ctr_set_stop(&cpuhw->state, hwc->config_base);
  444. event->hw.state |= PERF_HES_STOPPED;
  445. }
  446. if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
  447. hw_perf_event_update(event);
  448. event->hw.state |= PERF_HES_UPTODATE;
  449. }
  450. }
  451. static int cpumf_pmu_add(struct perf_event *event, int flags)
  452. {
  453. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  454. /* Check authorization for the counter set to which this
  455. * counter belongs.
  456. * For group events transaction, the authorization check is
  457. * done in cpumf_pmu_commit_txn().
  458. */
  459. if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD))
  460. if (validate_ctr_auth(&event->hw))
  461. return -ENOENT;
  462. ctr_set_enable(&cpuhw->state, event->hw.config_base);
  463. event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
  464. if (flags & PERF_EF_START)
  465. cpumf_pmu_start(event, PERF_EF_RELOAD);
  466. perf_event_update_userpage(event);
  467. return 0;
  468. }
  469. static void cpumf_pmu_del(struct perf_event *event, int flags)
  470. {
  471. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  472. cpumf_pmu_stop(event, PERF_EF_UPDATE);
  473. /* Check if any counter in the counter set is still used. If not used,
  474. * change the counter set to the disabled state. This also clears the
  475. * content of all counters in the set.
  476. *
  477. * When a new perf event has been added but not yet started, this can
  478. * clear enable control and resets all counters in a set. Therefore,
  479. * cpumf_pmu_start() always has to reenable a counter set.
  480. */
  481. if (!atomic_read(&cpuhw->ctr_set[event->hw.config_base]))
  482. ctr_set_disable(&cpuhw->state, event->hw.config_base);
  483. perf_event_update_userpage(event);
  484. }
  485. /*
  486. * Start group events scheduling transaction.
  487. * Set flags to perform a single test at commit time.
  488. *
  489. * We only support PERF_PMU_TXN_ADD transactions. Save the
  490. * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
  491. * transactions.
  492. */
  493. static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
  494. {
  495. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  496. WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
  497. cpuhw->txn_flags = txn_flags;
  498. if (txn_flags & ~PERF_PMU_TXN_ADD)
  499. return;
  500. perf_pmu_disable(pmu);
  501. cpuhw->tx_state = cpuhw->state;
  502. }
  503. /*
  504. * Stop and cancel a group events scheduling tranctions.
  505. * Assumes cpumf_pmu_del() is called for each successful added
  506. * cpumf_pmu_add() during the transaction.
  507. */
  508. static void cpumf_pmu_cancel_txn(struct pmu *pmu)
  509. {
  510. unsigned int txn_flags;
  511. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  512. WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
  513. txn_flags = cpuhw->txn_flags;
  514. cpuhw->txn_flags = 0;
  515. if (txn_flags & ~PERF_PMU_TXN_ADD)
  516. return;
  517. WARN_ON(cpuhw->tx_state != cpuhw->state);
  518. perf_pmu_enable(pmu);
  519. }
  520. /*
  521. * Commit the group events scheduling transaction. On success, the
  522. * transaction is closed. On error, the transaction is kept open
  523. * until cpumf_pmu_cancel_txn() is called.
  524. */
  525. static int cpumf_pmu_commit_txn(struct pmu *pmu)
  526. {
  527. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  528. u64 state;
  529. WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
  530. if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
  531. cpuhw->txn_flags = 0;
  532. return 0;
  533. }
  534. /* check if the updated state can be scheduled */
  535. state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
  536. state >>= CPUMF_LCCTL_ENABLE_SHIFT;
  537. if ((state & cpuhw->info.auth_ctl) != state)
  538. return -ENOENT;
  539. cpuhw->txn_flags = 0;
  540. perf_pmu_enable(pmu);
  541. return 0;
  542. }
  543. /* Performance monitoring unit for s390x */
  544. static struct pmu cpumf_pmu = {
  545. .task_ctx_nr = perf_sw_context,
  546. .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
  547. .pmu_enable = cpumf_pmu_enable,
  548. .pmu_disable = cpumf_pmu_disable,
  549. .event_init = cpumf_pmu_event_init,
  550. .add = cpumf_pmu_add,
  551. .del = cpumf_pmu_del,
  552. .start = cpumf_pmu_start,
  553. .stop = cpumf_pmu_stop,
  554. .read = cpumf_pmu_read,
  555. .start_txn = cpumf_pmu_start_txn,
  556. .commit_txn = cpumf_pmu_commit_txn,
  557. .cancel_txn = cpumf_pmu_cancel_txn,
  558. };
  559. static int cpumf_pmf_setup(unsigned int cpu, int flags)
  560. {
  561. local_irq_disable();
  562. setup_pmc_cpu(&flags);
  563. local_irq_enable();
  564. return 0;
  565. }
  566. static int s390_pmu_online_cpu(unsigned int cpu)
  567. {
  568. return cpumf_pmf_setup(cpu, PMC_INIT);
  569. }
  570. static int s390_pmu_offline_cpu(unsigned int cpu)
  571. {
  572. return cpumf_pmf_setup(cpu, PMC_RELEASE);
  573. }
  574. static int __init cpumf_pmu_init(void)
  575. {
  576. int rc;
  577. if (!cpum_cf_avail())
  578. return -ENODEV;
  579. /* clear bit 15 of cr0 to unauthorize problem-state to
  580. * extract measurement counters */
  581. ctl_clear_bit(0, 48);
  582. /* register handler for measurement-alert interruptions */
  583. rc = register_external_irq(EXT_IRQ_MEASURE_ALERT,
  584. cpumf_measurement_alert);
  585. if (rc) {
  586. pr_err("Registering for CPU-measurement alerts "
  587. "failed with rc=%i\n", rc);
  588. return rc;
  589. }
  590. cpumf_pmu.attr_groups = cpumf_cf_event_group();
  591. rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
  592. if (rc) {
  593. pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
  594. unregister_external_irq(EXT_IRQ_MEASURE_ALERT,
  595. cpumf_measurement_alert);
  596. return rc;
  597. }
  598. return cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE,
  599. "AP_PERF_S390_CF_ONLINE",
  600. s390_pmu_online_cpu, s390_pmu_offline_cpu);
  601. }
  602. early_initcall(cpumf_pmu_init);