arm_brbe.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Branch Record Buffer Extension Driver.
  4. *
  5. * Copyright (C) 2022-2025 ARM Limited
  6. *
  7. * Author: Anshuman Khandual <anshuman.khandual@arm.com>
  8. */
  9. #include <linux/types.h>
  10. #include <linux/bitmap.h>
  11. #include <linux/perf/arm_pmu.h>
  12. #include "arm_brbe.h"
  13. #define BRBFCR_EL1_BRANCH_FILTERS (BRBFCR_EL1_DIRECT | \
  14. BRBFCR_EL1_INDIRECT | \
  15. BRBFCR_EL1_RTN | \
  16. BRBFCR_EL1_INDCALL | \
  17. BRBFCR_EL1_DIRCALL | \
  18. BRBFCR_EL1_CONDDIR)
  19. /*
  20. * BRBTS_EL1 is currently not used for branch stack implementation
  21. * purpose but BRBCR_ELx.TS needs to have a valid value from all
  22. * available options. BRBCR_ELx_TS_VIRTUAL is selected for this.
  23. */
  24. #define BRBCR_ELx_DEFAULT_TS FIELD_PREP(BRBCR_ELx_TS_MASK, BRBCR_ELx_TS_VIRTUAL)
  25. /*
  26. * BRBE Buffer Organization
  27. *
  28. * BRBE buffer is arranged as multiple banks of 32 branch record
  29. * entries each. An individual branch record in a given bank could
  30. * be accessed, after selecting the bank in BRBFCR_EL1.BANK and
  31. * accessing the registers i.e [BRBSRC, BRBTGT, BRBINF] set with
  32. * indices [0..31].
  33. *
  34. * Bank 0
  35. *
  36. * --------------------------------- ------
  37. * | 00 | BRBSRC | BRBTGT | BRBINF | | 00 |
  38. * --------------------------------- ------
  39. * | 01 | BRBSRC | BRBTGT | BRBINF | | 01 |
  40. * --------------------------------- ------
  41. * | .. | BRBSRC | BRBTGT | BRBINF | | .. |
  42. * --------------------------------- ------
  43. * | 31 | BRBSRC | BRBTGT | BRBINF | | 31 |
  44. * --------------------------------- ------
  45. *
  46. * Bank 1
  47. *
  48. * --------------------------------- ------
  49. * | 32 | BRBSRC | BRBTGT | BRBINF | | 00 |
  50. * --------------------------------- ------
  51. * | 33 | BRBSRC | BRBTGT | BRBINF | | 01 |
  52. * --------------------------------- ------
  53. * | .. | BRBSRC | BRBTGT | BRBINF | | .. |
  54. * --------------------------------- ------
  55. * | 63 | BRBSRC | BRBTGT | BRBINF | | 31 |
  56. * --------------------------------- ------
  57. */
  58. #define BRBE_BANK_MAX_ENTRIES 32
  59. struct brbe_regset {
  60. u64 brbsrc;
  61. u64 brbtgt;
  62. u64 brbinf;
  63. };
  64. #define PERF_BR_ARM64_MAX (PERF_BR_MAX + PERF_BR_NEW_MAX)
  65. struct brbe_hw_attr {
  66. int brbe_version;
  67. int brbe_cc;
  68. int brbe_nr;
  69. int brbe_format;
  70. };
  71. #define BRBE_REGN_CASE(n, case_macro) \
  72. case n: case_macro(n); break
  73. #define BRBE_REGN_SWITCH(x, case_macro) \
  74. do { \
  75. switch (x) { \
  76. BRBE_REGN_CASE(0, case_macro); \
  77. BRBE_REGN_CASE(1, case_macro); \
  78. BRBE_REGN_CASE(2, case_macro); \
  79. BRBE_REGN_CASE(3, case_macro); \
  80. BRBE_REGN_CASE(4, case_macro); \
  81. BRBE_REGN_CASE(5, case_macro); \
  82. BRBE_REGN_CASE(6, case_macro); \
  83. BRBE_REGN_CASE(7, case_macro); \
  84. BRBE_REGN_CASE(8, case_macro); \
  85. BRBE_REGN_CASE(9, case_macro); \
  86. BRBE_REGN_CASE(10, case_macro); \
  87. BRBE_REGN_CASE(11, case_macro); \
  88. BRBE_REGN_CASE(12, case_macro); \
  89. BRBE_REGN_CASE(13, case_macro); \
  90. BRBE_REGN_CASE(14, case_macro); \
  91. BRBE_REGN_CASE(15, case_macro); \
  92. BRBE_REGN_CASE(16, case_macro); \
  93. BRBE_REGN_CASE(17, case_macro); \
  94. BRBE_REGN_CASE(18, case_macro); \
  95. BRBE_REGN_CASE(19, case_macro); \
  96. BRBE_REGN_CASE(20, case_macro); \
  97. BRBE_REGN_CASE(21, case_macro); \
  98. BRBE_REGN_CASE(22, case_macro); \
  99. BRBE_REGN_CASE(23, case_macro); \
  100. BRBE_REGN_CASE(24, case_macro); \
  101. BRBE_REGN_CASE(25, case_macro); \
  102. BRBE_REGN_CASE(26, case_macro); \
  103. BRBE_REGN_CASE(27, case_macro); \
  104. BRBE_REGN_CASE(28, case_macro); \
  105. BRBE_REGN_CASE(29, case_macro); \
  106. BRBE_REGN_CASE(30, case_macro); \
  107. BRBE_REGN_CASE(31, case_macro); \
  108. default: WARN(1, "Invalid BRB* index %d\n", x); \
  109. } \
  110. } while (0)
  111. #define RETURN_READ_BRBSRCN(n) \
  112. return read_sysreg_s(SYS_BRBSRC_EL1(n))
  113. static inline u64 get_brbsrc_reg(int idx)
  114. {
  115. BRBE_REGN_SWITCH(idx, RETURN_READ_BRBSRCN);
  116. return 0;
  117. }
  118. #define RETURN_READ_BRBTGTN(n) \
  119. return read_sysreg_s(SYS_BRBTGT_EL1(n))
  120. static u64 get_brbtgt_reg(int idx)
  121. {
  122. BRBE_REGN_SWITCH(idx, RETURN_READ_BRBTGTN);
  123. return 0;
  124. }
  125. #define RETURN_READ_BRBINFN(n) \
  126. return read_sysreg_s(SYS_BRBINF_EL1(n))
  127. static u64 get_brbinf_reg(int idx)
  128. {
  129. BRBE_REGN_SWITCH(idx, RETURN_READ_BRBINFN);
  130. return 0;
  131. }
  132. static u64 brbe_record_valid(u64 brbinf)
  133. {
  134. return FIELD_GET(BRBINFx_EL1_VALID_MASK, brbinf);
  135. }
  136. static bool brbe_invalid(u64 brbinf)
  137. {
  138. return brbe_record_valid(brbinf) == BRBINFx_EL1_VALID_NONE;
  139. }
  140. static bool brbe_record_is_complete(u64 brbinf)
  141. {
  142. return brbe_record_valid(brbinf) == BRBINFx_EL1_VALID_FULL;
  143. }
  144. static bool brbe_record_is_source_only(u64 brbinf)
  145. {
  146. return brbe_record_valid(brbinf) == BRBINFx_EL1_VALID_SOURCE;
  147. }
  148. static bool brbe_record_is_target_only(u64 brbinf)
  149. {
  150. return brbe_record_valid(brbinf) == BRBINFx_EL1_VALID_TARGET;
  151. }
  152. static int brbinf_get_in_tx(u64 brbinf)
  153. {
  154. return FIELD_GET(BRBINFx_EL1_T_MASK, brbinf);
  155. }
  156. static int brbinf_get_mispredict(u64 brbinf)
  157. {
  158. return FIELD_GET(BRBINFx_EL1_MPRED_MASK, brbinf);
  159. }
  160. static int brbinf_get_lastfailed(u64 brbinf)
  161. {
  162. return FIELD_GET(BRBINFx_EL1_LASTFAILED_MASK, brbinf);
  163. }
  164. static u16 brbinf_get_cycles(u64 brbinf)
  165. {
  166. u32 exp, mant, cycles;
  167. /*
  168. * Captured cycle count is unknown and hence
  169. * should not be passed on to userspace.
  170. */
  171. if (brbinf & BRBINFx_EL1_CCU)
  172. return 0;
  173. exp = FIELD_GET(BRBINFx_EL1_CC_EXP_MASK, brbinf);
  174. mant = FIELD_GET(BRBINFx_EL1_CC_MANT_MASK, brbinf);
  175. if (!exp)
  176. return mant;
  177. cycles = (mant | 0x100) << (exp - 1);
  178. return min(cycles, U16_MAX);
  179. }
  180. static int brbinf_get_type(u64 brbinf)
  181. {
  182. return FIELD_GET(BRBINFx_EL1_TYPE_MASK, brbinf);
  183. }
  184. static int brbinf_get_el(u64 brbinf)
  185. {
  186. return FIELD_GET(BRBINFx_EL1_EL_MASK, brbinf);
  187. }
  188. void brbe_invalidate(void)
  189. {
  190. /* Ensure all branches before this point are recorded */
  191. isb();
  192. asm volatile(BRB_IALL_INSN);
  193. /* Ensure all branch records are invalidated after this point */
  194. isb();
  195. }
  196. static bool valid_brbe_nr(int brbe_nr)
  197. {
  198. return brbe_nr == BRBIDR0_EL1_NUMREC_8 ||
  199. brbe_nr == BRBIDR0_EL1_NUMREC_16 ||
  200. brbe_nr == BRBIDR0_EL1_NUMREC_32 ||
  201. brbe_nr == BRBIDR0_EL1_NUMREC_64;
  202. }
  203. static bool valid_brbe_cc(int brbe_cc)
  204. {
  205. return brbe_cc == BRBIDR0_EL1_CC_20_BIT;
  206. }
  207. static bool valid_brbe_format(int brbe_format)
  208. {
  209. return brbe_format == BRBIDR0_EL1_FORMAT_FORMAT_0;
  210. }
  211. static bool valid_brbidr(u64 brbidr)
  212. {
  213. int brbe_format, brbe_cc, brbe_nr;
  214. brbe_format = FIELD_GET(BRBIDR0_EL1_FORMAT_MASK, brbidr);
  215. brbe_cc = FIELD_GET(BRBIDR0_EL1_CC_MASK, brbidr);
  216. brbe_nr = FIELD_GET(BRBIDR0_EL1_NUMREC_MASK, brbidr);
  217. return valid_brbe_format(brbe_format) && valid_brbe_cc(brbe_cc) && valid_brbe_nr(brbe_nr);
  218. }
  219. static bool valid_brbe_version(int brbe_version)
  220. {
  221. return brbe_version == ID_AA64DFR0_EL1_BRBE_IMP ||
  222. brbe_version == ID_AA64DFR0_EL1_BRBE_BRBE_V1P1;
  223. }
  224. static void select_brbe_bank(int bank)
  225. {
  226. u64 brbfcr;
  227. brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
  228. brbfcr &= ~BRBFCR_EL1_BANK_MASK;
  229. brbfcr |= SYS_FIELD_PREP(BRBFCR_EL1, BANK, bank);
  230. write_sysreg_s(brbfcr, SYS_BRBFCR_EL1);
  231. /*
  232. * Arm ARM (DDI 0487K.a) D.18.4 rule PPBZP requires explicit sync
  233. * between setting BANK and accessing branch records.
  234. */
  235. isb();
  236. }
  237. static bool __read_brbe_regset(struct brbe_regset *entry, int idx)
  238. {
  239. entry->brbinf = get_brbinf_reg(idx);
  240. if (brbe_invalid(entry->brbinf))
  241. return false;
  242. entry->brbsrc = get_brbsrc_reg(idx);
  243. entry->brbtgt = get_brbtgt_reg(idx);
  244. return true;
  245. }
  246. /*
  247. * Generic perf branch filters supported on BRBE
  248. *
  249. * New branch filters need to be evaluated whether they could be supported on
  250. * BRBE. This ensures that such branch filters would not just be accepted, to
  251. * fail silently. PERF_SAMPLE_BRANCH_HV is a special case that is selectively
  252. * supported only on platforms where kernel is in hyp mode.
  253. */
  254. #define BRBE_EXCLUDE_BRANCH_FILTERS (PERF_SAMPLE_BRANCH_ABORT_TX | \
  255. PERF_SAMPLE_BRANCH_IN_TX | \
  256. PERF_SAMPLE_BRANCH_NO_TX | \
  257. PERF_SAMPLE_BRANCH_CALL_STACK | \
  258. PERF_SAMPLE_BRANCH_COUNTERS)
  259. #define BRBE_ALLOWED_BRANCH_TYPES (PERF_SAMPLE_BRANCH_ANY | \
  260. PERF_SAMPLE_BRANCH_ANY_CALL | \
  261. PERF_SAMPLE_BRANCH_ANY_RETURN | \
  262. PERF_SAMPLE_BRANCH_IND_CALL | \
  263. PERF_SAMPLE_BRANCH_COND | \
  264. PERF_SAMPLE_BRANCH_IND_JUMP | \
  265. PERF_SAMPLE_BRANCH_CALL)
  266. #define BRBE_ALLOWED_BRANCH_FILTERS (PERF_SAMPLE_BRANCH_USER | \
  267. PERF_SAMPLE_BRANCH_KERNEL | \
  268. PERF_SAMPLE_BRANCH_HV | \
  269. BRBE_ALLOWED_BRANCH_TYPES | \
  270. PERF_SAMPLE_BRANCH_NO_FLAGS | \
  271. PERF_SAMPLE_BRANCH_NO_CYCLES | \
  272. PERF_SAMPLE_BRANCH_TYPE_SAVE | \
  273. PERF_SAMPLE_BRANCH_HW_INDEX | \
  274. PERF_SAMPLE_BRANCH_PRIV_SAVE)
  275. #define BRBE_PERF_BRANCH_FILTERS (BRBE_ALLOWED_BRANCH_FILTERS | \
  276. BRBE_EXCLUDE_BRANCH_FILTERS)
  277. /*
  278. * BRBE supports the following functional branch type filters while
  279. * generating branch records. These branch filters can be enabled,
  280. * either individually or as a group i.e ORing multiple filters
  281. * with each other.
  282. *
  283. * BRBFCR_EL1_CONDDIR - Conditional direct branch
  284. * BRBFCR_EL1_DIRCALL - Direct call
  285. * BRBFCR_EL1_INDCALL - Indirect call
  286. * BRBFCR_EL1_INDIRECT - Indirect branch
  287. * BRBFCR_EL1_DIRECT - Direct branch
  288. * BRBFCR_EL1_RTN - Subroutine return
  289. */
  290. static u64 branch_type_to_brbfcr(int branch_type)
  291. {
  292. u64 brbfcr = 0;
  293. if (branch_type & PERF_SAMPLE_BRANCH_ANY) {
  294. brbfcr |= BRBFCR_EL1_BRANCH_FILTERS;
  295. return brbfcr;
  296. }
  297. if (branch_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
  298. brbfcr |= BRBFCR_EL1_INDCALL;
  299. brbfcr |= BRBFCR_EL1_DIRCALL;
  300. }
  301. if (branch_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
  302. brbfcr |= BRBFCR_EL1_RTN;
  303. if (branch_type & PERF_SAMPLE_BRANCH_IND_CALL)
  304. brbfcr |= BRBFCR_EL1_INDCALL;
  305. if (branch_type & PERF_SAMPLE_BRANCH_COND)
  306. brbfcr |= BRBFCR_EL1_CONDDIR;
  307. if (branch_type & PERF_SAMPLE_BRANCH_IND_JUMP)
  308. brbfcr |= BRBFCR_EL1_INDIRECT;
  309. if (branch_type & PERF_SAMPLE_BRANCH_CALL)
  310. brbfcr |= BRBFCR_EL1_DIRCALL;
  311. return brbfcr;
  312. }
  313. /*
  314. * BRBE supports the following privilege mode filters while generating
  315. * branch records.
  316. *
  317. * BRBCR_ELx_E0BRE - EL0 branch records
  318. * BRBCR_ELx_ExBRE - EL1/EL2 branch records
  319. *
  320. * BRBE also supports the following additional functional branch type
  321. * filters while generating branch records.
  322. *
  323. * BRBCR_ELx_EXCEPTION - Exception
  324. * BRBCR_ELx_ERTN - Exception return
  325. */
  326. static u64 branch_type_to_brbcr(int branch_type)
  327. {
  328. u64 brbcr = BRBCR_ELx_FZP | BRBCR_ELx_DEFAULT_TS;
  329. if (branch_type & PERF_SAMPLE_BRANCH_USER)
  330. brbcr |= BRBCR_ELx_E0BRE;
  331. /*
  332. * When running in the hyp mode, writing into BRBCR_EL1
  333. * actually writes into BRBCR_EL2 instead. Field E2BRE
  334. * is also at the same position as E1BRE.
  335. */
  336. if (branch_type & PERF_SAMPLE_BRANCH_KERNEL)
  337. brbcr |= BRBCR_ELx_ExBRE;
  338. if (branch_type & PERF_SAMPLE_BRANCH_HV) {
  339. if (is_kernel_in_hyp_mode())
  340. brbcr |= BRBCR_ELx_ExBRE;
  341. }
  342. if (!(branch_type & PERF_SAMPLE_BRANCH_NO_CYCLES))
  343. brbcr |= BRBCR_ELx_CC;
  344. if (!(branch_type & PERF_SAMPLE_BRANCH_NO_FLAGS))
  345. brbcr |= BRBCR_ELx_MPRED;
  346. /*
  347. * The exception and exception return branches could be
  348. * captured, irrespective of the perf event's privilege.
  349. * If the perf event does not have enough privilege for
  350. * a given exception level, then addresses which falls
  351. * under that exception level will be reported as zero
  352. * for the captured branch record, creating source only
  353. * or target only records.
  354. */
  355. if (branch_type & PERF_SAMPLE_BRANCH_KERNEL) {
  356. if (branch_type & PERF_SAMPLE_BRANCH_ANY) {
  357. brbcr |= BRBCR_ELx_EXCEPTION;
  358. brbcr |= BRBCR_ELx_ERTN;
  359. }
  360. if (branch_type & PERF_SAMPLE_BRANCH_ANY_CALL)
  361. brbcr |= BRBCR_ELx_EXCEPTION;
  362. if (branch_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
  363. brbcr |= BRBCR_ELx_ERTN;
  364. }
  365. return brbcr;
  366. }
  367. bool brbe_branch_attr_valid(struct perf_event *event)
  368. {
  369. u64 branch_type = event->attr.branch_sample_type;
  370. /*
  371. * Ensure both perf branch filter allowed and exclude
  372. * masks are always in sync with the generic perf ABI.
  373. */
  374. BUILD_BUG_ON(BRBE_PERF_BRANCH_FILTERS != (PERF_SAMPLE_BRANCH_MAX - 1));
  375. if (branch_type & BRBE_EXCLUDE_BRANCH_FILTERS) {
  376. pr_debug("requested branch filter not supported 0x%llx\n", branch_type);
  377. return false;
  378. }
  379. /* Ensure at least 1 branch type is enabled */
  380. if (!(branch_type & BRBE_ALLOWED_BRANCH_TYPES)) {
  381. pr_debug("no branch type enabled 0x%llx\n", branch_type);
  382. return false;
  383. }
  384. /*
  385. * No branches are recorded in guests nor nVHE hypervisors, so
  386. * excluding the host or both kernel and user is invalid.
  387. *
  388. * Ideally we'd just require exclude_guest and exclude_hv, but setting
  389. * event filters with perf for kernel or user don't set exclude_guest.
  390. * So effectively, exclude_guest and exclude_hv are ignored.
  391. */
  392. if (event->attr.exclude_host || (event->attr.exclude_user && event->attr.exclude_kernel)) {
  393. pr_debug("branch filter in hypervisor or guest only not supported 0x%llx\n", branch_type);
  394. return false;
  395. }
  396. event->hw.branch_reg.config = branch_type_to_brbfcr(event->attr.branch_sample_type);
  397. event->hw.extra_reg.config = branch_type_to_brbcr(event->attr.branch_sample_type);
  398. return true;
  399. }
  400. unsigned int brbe_num_branch_records(const struct arm_pmu *armpmu)
  401. {
  402. return FIELD_GET(BRBIDR0_EL1_NUMREC_MASK, armpmu->reg_brbidr);
  403. }
  404. void brbe_probe(struct arm_pmu *armpmu)
  405. {
  406. u64 brbidr, aa64dfr0 = read_sysreg_s(SYS_ID_AA64DFR0_EL1);
  407. u32 brbe;
  408. brbe = cpuid_feature_extract_unsigned_field(aa64dfr0, ID_AA64DFR0_EL1_BRBE_SHIFT);
  409. if (!valid_brbe_version(brbe))
  410. return;
  411. brbidr = read_sysreg_s(SYS_BRBIDR0_EL1);
  412. if (!valid_brbidr(brbidr))
  413. return;
  414. armpmu->reg_brbidr = brbidr;
  415. }
  416. /*
  417. * BRBE is assumed to be disabled/paused on entry
  418. */
  419. void brbe_enable(const struct arm_pmu *arm_pmu)
  420. {
  421. struct pmu_hw_events *cpuc = this_cpu_ptr(arm_pmu->hw_events);
  422. u64 brbfcr = 0, brbcr = 0;
  423. /*
  424. * Discard existing records to avoid a discontinuity, e.g. records
  425. * missed during handling an overflow.
  426. */
  427. brbe_invalidate();
  428. /*
  429. * Merge the permitted branch filters of all events.
  430. */
  431. for (int i = 0; i < ARMPMU_MAX_HWEVENTS; i++) {
  432. struct perf_event *event = cpuc->events[i];
  433. if (event && has_branch_stack(event)) {
  434. brbfcr |= event->hw.branch_reg.config;
  435. brbcr |= event->hw.extra_reg.config;
  436. }
  437. }
  438. /*
  439. * In VHE mode with MDCR_EL2.HPMN equal to PMCR_EL0.N, BRBCR_EL1.FZP
  440. * controls freezing the branch records on counter overflow rather than
  441. * BRBCR_EL2.FZP (which writes to BRBCR_EL1 are redirected to).
  442. * The exception levels are enabled/disabled in BRBCR_EL2, so keep EL1
  443. * and EL0 recording disabled for guests.
  444. *
  445. * As BRBCR_EL1 CC and MPRED bits also need to match, use the same
  446. * value for both registers just masking the exception levels.
  447. */
  448. if (is_kernel_in_hyp_mode())
  449. write_sysreg_s(brbcr & ~(BRBCR_ELx_ExBRE | BRBCR_ELx_E0BRE), SYS_BRBCR_EL12);
  450. write_sysreg_s(brbcr, SYS_BRBCR_EL1);
  451. /* Ensure BRBCR_ELx settings take effect before unpausing */
  452. isb();
  453. /* Finally write SYS_BRBFCR_EL to unpause BRBE */
  454. write_sysreg_s(brbfcr, SYS_BRBFCR_EL1);
  455. /* Synchronization in PMCR write ensures ordering WRT PMU enabling */
  456. }
  457. void brbe_disable(void)
  458. {
  459. /*
  460. * No need for synchronization here as synchronization in PMCR write
  461. * ensures ordering and in the interrupt handler this is a NOP as
  462. * we're already paused.
  463. */
  464. write_sysreg_s(BRBFCR_EL1_PAUSED, SYS_BRBFCR_EL1);
  465. write_sysreg_s(0, SYS_BRBCR_EL1);
  466. }
  467. static const int brbe_type_to_perf_type_map[BRBINFx_EL1_TYPE_DEBUG_EXIT + 1][2] = {
  468. [BRBINFx_EL1_TYPE_DIRECT_UNCOND] = { PERF_BR_UNCOND, 0 },
  469. [BRBINFx_EL1_TYPE_INDIRECT] = { PERF_BR_IND, 0 },
  470. [BRBINFx_EL1_TYPE_DIRECT_LINK] = { PERF_BR_CALL, 0 },
  471. [BRBINFx_EL1_TYPE_INDIRECT_LINK] = { PERF_BR_IND_CALL, 0 },
  472. [BRBINFx_EL1_TYPE_RET] = { PERF_BR_RET, 0 },
  473. [BRBINFx_EL1_TYPE_DIRECT_COND] = { PERF_BR_COND, 0 },
  474. [BRBINFx_EL1_TYPE_CALL] = { PERF_BR_SYSCALL, 0 },
  475. [BRBINFx_EL1_TYPE_ERET] = { PERF_BR_ERET, 0 },
  476. [BRBINFx_EL1_TYPE_IRQ] = { PERF_BR_IRQ, 0 },
  477. [BRBINFx_EL1_TYPE_TRAP] = { PERF_BR_IRQ, 0 },
  478. [BRBINFx_EL1_TYPE_SERROR] = { PERF_BR_SERROR, 0 },
  479. [BRBINFx_EL1_TYPE_ALIGN_FAULT] = { PERF_BR_EXTEND_ABI, PERF_BR_NEW_FAULT_ALGN },
  480. [BRBINFx_EL1_TYPE_INSN_FAULT] = { PERF_BR_EXTEND_ABI, PERF_BR_NEW_FAULT_INST },
  481. [BRBINFx_EL1_TYPE_DATA_FAULT] = { PERF_BR_EXTEND_ABI, PERF_BR_NEW_FAULT_DATA },
  482. };
  483. static void brbe_set_perf_entry_type(struct perf_branch_entry *entry, u64 brbinf)
  484. {
  485. int brbe_type = brbinf_get_type(brbinf);
  486. if (brbe_type <= BRBINFx_EL1_TYPE_DEBUG_EXIT) {
  487. const int *br_type = brbe_type_to_perf_type_map[brbe_type];
  488. entry->type = br_type[0];
  489. entry->new_type = br_type[1];
  490. }
  491. }
  492. static int brbinf_get_perf_priv(u64 brbinf)
  493. {
  494. int brbe_el = brbinf_get_el(brbinf);
  495. switch (brbe_el) {
  496. case BRBINFx_EL1_EL_EL0:
  497. return PERF_BR_PRIV_USER;
  498. case BRBINFx_EL1_EL_EL1:
  499. return PERF_BR_PRIV_KERNEL;
  500. case BRBINFx_EL1_EL_EL2:
  501. if (is_kernel_in_hyp_mode())
  502. return PERF_BR_PRIV_KERNEL;
  503. return PERF_BR_PRIV_HV;
  504. default:
  505. pr_warn_once("%d - unknown branch privilege captured\n", brbe_el);
  506. return PERF_BR_PRIV_UNKNOWN;
  507. }
  508. }
  509. static bool perf_entry_from_brbe_regset(int index, struct perf_branch_entry *entry,
  510. const struct perf_event *event)
  511. {
  512. struct brbe_regset bregs;
  513. u64 brbinf;
  514. if (!__read_brbe_regset(&bregs, index))
  515. return false;
  516. brbinf = bregs.brbinf;
  517. perf_clear_branch_entry_bitfields(entry);
  518. if (brbe_record_is_complete(brbinf)) {
  519. entry->from = bregs.brbsrc;
  520. entry->to = bregs.brbtgt;
  521. } else if (brbe_record_is_source_only(brbinf)) {
  522. entry->from = bregs.brbsrc;
  523. entry->to = 0;
  524. } else if (brbe_record_is_target_only(brbinf)) {
  525. entry->from = 0;
  526. entry->to = bregs.brbtgt;
  527. }
  528. brbe_set_perf_entry_type(entry, brbinf);
  529. if (!branch_sample_no_cycles(event))
  530. entry->cycles = brbinf_get_cycles(brbinf);
  531. if (!branch_sample_no_flags(event)) {
  532. /* Mispredict info is available for source only and complete branch records. */
  533. if (!brbe_record_is_target_only(brbinf)) {
  534. entry->mispred = brbinf_get_mispredict(brbinf);
  535. entry->predicted = !entry->mispred;
  536. }
  537. /*
  538. * Currently TME feature is neither implemented in any hardware
  539. * nor it is being supported in the kernel. Just warn here once
  540. * if TME related information shows up rather unexpectedly.
  541. */
  542. if (brbinf_get_lastfailed(brbinf) || brbinf_get_in_tx(brbinf))
  543. pr_warn_once("Unknown transaction states\n");
  544. }
  545. /*
  546. * Branch privilege level is available for target only and complete
  547. * branch records.
  548. */
  549. if (!brbe_record_is_source_only(brbinf))
  550. entry->priv = brbinf_get_perf_priv(brbinf);
  551. return true;
  552. }
  553. #define PERF_BR_ARM64_ALL ( \
  554. BIT(PERF_BR_COND) | \
  555. BIT(PERF_BR_UNCOND) | \
  556. BIT(PERF_BR_IND) | \
  557. BIT(PERF_BR_CALL) | \
  558. BIT(PERF_BR_IND_CALL) | \
  559. BIT(PERF_BR_RET))
  560. #define PERF_BR_ARM64_ALL_KERNEL ( \
  561. BIT(PERF_BR_SYSCALL) | \
  562. BIT(PERF_BR_IRQ) | \
  563. BIT(PERF_BR_SERROR) | \
  564. BIT(PERF_BR_MAX + PERF_BR_NEW_FAULT_ALGN) | \
  565. BIT(PERF_BR_MAX + PERF_BR_NEW_FAULT_DATA) | \
  566. BIT(PERF_BR_MAX + PERF_BR_NEW_FAULT_INST))
  567. static void prepare_event_branch_type_mask(u64 branch_sample,
  568. unsigned long *event_type_mask)
  569. {
  570. if (branch_sample & PERF_SAMPLE_BRANCH_ANY) {
  571. if (branch_sample & PERF_SAMPLE_BRANCH_KERNEL)
  572. bitmap_from_u64(event_type_mask,
  573. BIT(PERF_BR_ERET) | PERF_BR_ARM64_ALL |
  574. PERF_BR_ARM64_ALL_KERNEL);
  575. else
  576. bitmap_from_u64(event_type_mask, PERF_BR_ARM64_ALL);
  577. return;
  578. }
  579. bitmap_zero(event_type_mask, PERF_BR_ARM64_MAX);
  580. if (branch_sample & PERF_SAMPLE_BRANCH_ANY_CALL) {
  581. if (branch_sample & PERF_SAMPLE_BRANCH_KERNEL)
  582. bitmap_from_u64(event_type_mask, PERF_BR_ARM64_ALL_KERNEL);
  583. set_bit(PERF_BR_CALL, event_type_mask);
  584. set_bit(PERF_BR_IND_CALL, event_type_mask);
  585. }
  586. if (branch_sample & PERF_SAMPLE_BRANCH_IND_JUMP)
  587. set_bit(PERF_BR_IND, event_type_mask);
  588. if (branch_sample & PERF_SAMPLE_BRANCH_COND)
  589. set_bit(PERF_BR_COND, event_type_mask);
  590. if (branch_sample & PERF_SAMPLE_BRANCH_CALL)
  591. set_bit(PERF_BR_CALL, event_type_mask);
  592. if (branch_sample & PERF_SAMPLE_BRANCH_IND_CALL)
  593. set_bit(PERF_BR_IND_CALL, event_type_mask);
  594. if (branch_sample & PERF_SAMPLE_BRANCH_ANY_RETURN) {
  595. set_bit(PERF_BR_RET, event_type_mask);
  596. if (branch_sample & PERF_SAMPLE_BRANCH_KERNEL)
  597. set_bit(PERF_BR_ERET, event_type_mask);
  598. }
  599. }
  600. /*
  601. * BRBE is configured with an OR of permissions from all events, so there may
  602. * be events which have to be dropped or events where just the source or target
  603. * address has to be zeroed.
  604. */
  605. static bool filter_branch_privilege(struct perf_branch_entry *entry, u64 branch_sample_type)
  606. {
  607. bool from_user = access_ok((void __user *)(unsigned long)entry->from, 4);
  608. bool to_user = access_ok((void __user *)(unsigned long)entry->to, 4);
  609. bool exclude_kernel = !((branch_sample_type & PERF_SAMPLE_BRANCH_KERNEL) ||
  610. (is_kernel_in_hyp_mode() && (branch_sample_type & PERF_SAMPLE_BRANCH_HV)));
  611. /* We can only have a half record if permissions have not been expanded */
  612. if (!entry->from || !entry->to)
  613. return true;
  614. /*
  615. * If record is within a single exception level, just need to either
  616. * drop or keep the entire record.
  617. */
  618. if (from_user == to_user)
  619. return ((entry->priv == PERF_BR_PRIV_KERNEL) && !exclude_kernel) ||
  620. ((entry->priv == PERF_BR_PRIV_USER) &&
  621. (branch_sample_type & PERF_SAMPLE_BRANCH_USER));
  622. /*
  623. * Record is across exception levels, mask addresses for the exception
  624. * level we're not capturing.
  625. */
  626. if (!(branch_sample_type & PERF_SAMPLE_BRANCH_USER)) {
  627. if (from_user)
  628. entry->from = 0;
  629. if (to_user)
  630. entry->to = 0;
  631. }
  632. if (exclude_kernel) {
  633. if (!from_user)
  634. entry->from = 0;
  635. if (!to_user)
  636. entry->to = 0;
  637. }
  638. return true;
  639. }
  640. static bool filter_branch_type(struct perf_branch_entry *entry,
  641. const unsigned long *event_type_mask)
  642. {
  643. if (entry->type == PERF_BR_EXTEND_ABI)
  644. return test_bit(PERF_BR_MAX + entry->new_type, event_type_mask);
  645. else
  646. return test_bit(entry->type, event_type_mask);
  647. }
  648. static bool filter_branch_record(struct perf_branch_entry *entry,
  649. u64 branch_sample,
  650. const unsigned long *event_type_mask)
  651. {
  652. return filter_branch_type(entry, event_type_mask) &&
  653. filter_branch_privilege(entry, branch_sample);
  654. }
  655. void brbe_read_filtered_entries(struct perf_branch_stack *branch_stack,
  656. const struct perf_event *event)
  657. {
  658. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  659. int nr_hw = brbe_num_branch_records(cpu_pmu);
  660. int nr_banks = DIV_ROUND_UP(nr_hw, BRBE_BANK_MAX_ENTRIES);
  661. int nr_filtered = 0;
  662. u64 branch_sample_type = event->attr.branch_sample_type;
  663. DECLARE_BITMAP(event_type_mask, PERF_BR_ARM64_MAX);
  664. prepare_event_branch_type_mask(branch_sample_type, event_type_mask);
  665. for (int bank = 0; bank < nr_banks; bank++) {
  666. int nr_remaining = nr_hw - (bank * BRBE_BANK_MAX_ENTRIES);
  667. int nr_this_bank = min(nr_remaining, BRBE_BANK_MAX_ENTRIES);
  668. select_brbe_bank(bank);
  669. for (int i = 0; i < nr_this_bank; i++) {
  670. struct perf_branch_entry *pbe = &branch_stack->entries[nr_filtered];
  671. if (!perf_entry_from_brbe_regset(i, pbe, event))
  672. goto done;
  673. if (!filter_branch_record(pbe, branch_sample_type, event_type_mask))
  674. continue;
  675. nr_filtered++;
  676. }
  677. }
  678. done:
  679. branch_stack->nr = nr_filtered;
  680. }