sparc: Add alignment and emulation fault perf events.

This mirrors commit 196f02bf900c5eb6f85d889c4f70e7cc11fda7e8
(powerpc: perf_event: Add alignment-faults and emulation-faults software events)

Signed-off-by: David S. Miller <davem@davemloft.net>

+20 -26
+3 -12
arch/sparc/kernel/unaligned_32.c
··· 17 17 #include <asm/uaccess.h> 18 18 #include <linux/smp.h> 19 19 #include <linux/smp_lock.h> 20 - 21 - /* #define DEBUG_MNA */ 20 + #include <linux/perf_event.h> 22 21 23 22 enum direction { 24 23 load, /* ld, ldd, ldh, ldsh */ ··· 27 28 fpstore, 28 29 invalid, 29 30 }; 30 - 31 - #ifdef DEBUG_MNA 32 - static char *dirstrings[] = { 33 - "load", "store", "both", "fpload", "fpstore", "invalid" 34 - }; 35 - #endif 36 31 37 32 static inline enum direction decode_direction(unsigned int insn) 38 33 { ··· 248 255 unsigned long addr = compute_effective_address(regs, insn); 249 256 int err; 250 257 251 - #ifdef DEBUG_MNA 252 - printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", 253 - regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); 254 - #endif 258 + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); 255 259 switch (dir) { 256 260 case load: 257 261 err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), ··· 340 350 } 341 351 342 352 addr = compute_effective_address(regs, insn); 353 + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); 343 354 switch(dir) { 344 355 case load: 345 356 err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
+9 -14
arch/sparc/kernel/unaligned_64.c
··· 20 20 #include <asm/uaccess.h> 21 21 #include <linux/smp.h> 22 22 #include <linux/bitops.h> 23 + #include <linux/perf_event.h> 23 24 #include <asm/fpumacro.h> 24 - 25 - /* #define DEBUG_MNA */ 26 25 27 26 enum direction { 28 27 load, /* ld, ldd, ldh, ldsh */ ··· 31 32 fpst, 32 33 invalid, 33 34 }; 34 - 35 - #ifdef DEBUG_MNA 36 - static char *dirstrings[] = { 37 - "load", "store", "both", "fpload", "fpstore", "invalid" 38 - }; 39 - #endif 40 35 41 36 static inline enum direction decode_direction(unsigned int insn) 42 37 { ··· 320 327 321 328 addr = compute_effective_address(regs, insn, 322 329 ((insn >> 25) & 0x1f)); 323 - #ifdef DEBUG_MNA 324 - printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " 325 - "retpc[%016lx]\n", 326 - regs->tpc, dirstrings[dir], addr, size, 327 - regs->u_regs[UREG_RETPC]); 328 - #endif 330 + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); 329 331 switch (asi) { 330 332 case ASI_NL: 331 333 case ASI_AIUPL: ··· 387 399 int ret, i, rd = ((insn >> 25) & 0x1f); 388 400 int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; 389 401 402 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 390 403 if (insn & 0x2000) { 391 404 maybe_flush_windows(0, 0, rd, from_kernel); 392 405 value = sign_extend_imm13(insn); ··· 433 444 struct fpustate *f = FPUSTATE; 434 445 int asi = decode_asi(insn, regs); 435 446 int flag = (freg < 32) ? FPRS_DL : FPRS_DU; 447 + 448 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 436 449 437 450 save_and_clear_fpu(); 438 451 current_thread_info()->xfsr[0] &= ~0x1c000; ··· 557 566 int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; 558 567 unsigned long *reg; 559 568 569 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 570 + 560 571 maybe_flush_windows(0, 0, rd, from_kernel); 561 572 reg = fetch_reg_addr(rd, regs); 562 573 if (from_kernel || rd < 16) { ··· 589 596 590 597 if (tstate & TSTATE_PRIV) 591 598 die_if_kernel("lddfmna from kernel", regs); 599 + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); 592 600 if (test_thread_flag(TIF_32BIT)) 593 601 pc = (u32)pc; 594 602 if (get_user(insn, (u32 __user *) pc) != -EFAULT) { ··· 651 657 652 658 if (tstate & TSTATE_PRIV) 653 659 die_if_kernel("stdfmna from kernel", regs); 660 + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); 654 661 if (test_thread_flag(TIF_32BIT)) 655 662 pc = (u32)pc; 656 663 if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
+3
arch/sparc/kernel/visemul.c
··· 5 5 #include <linux/kernel.h> 6 6 #include <linux/errno.h> 7 7 #include <linux/thread_info.h> 8 + #include <linux/perf_event.h> 8 9 9 10 #include <asm/ptrace.h> 10 11 #include <asm/pstate.h> ··· 801 800 unsigned int opf; 802 801 803 802 BUG_ON(regs->tstate & TSTATE_PRIV); 803 + 804 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 804 805 805 806 if (test_thread_flag(TIF_32BIT)) 806 807 pc = (u32)pc;
+3
arch/sparc/math-emu/math_32.c
··· 67 67 #include <linux/types.h> 68 68 #include <linux/sched.h> 69 69 #include <linux/mm.h> 70 + #include <linux/perf_event.h> 70 71 #include <asm/uaccess.h> 71 72 72 73 #include "sfp-util_32.h" ··· 163 162 int i; 164 163 int retcode = 0; /* assume all succeed */ 165 164 unsigned long insn; 165 + 166 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 166 167 167 168 #ifdef DEBUG_MATHEMU 168 169 printk("In do_mathemu()... pc is %08lx\n", regs->pc);
+2
arch/sparc/math-emu/math_64.c
··· 11 11 #include <linux/types.h> 12 12 #include <linux/sched.h> 13 13 #include <linux/errno.h> 14 + #include <linux/perf_event.h> 14 15 15 16 #include <asm/fpumacro.h> 16 17 #include <asm/ptrace.h> ··· 184 183 185 184 if (tstate & TSTATE_PRIV) 186 185 die_if_kernel("unfinished/unimplemented FPop from kernel", regs); 186 + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); 187 187 if (test_thread_flag(TIF_32BIT)) 188 188 pc = (u32)pc; 189 189 if (get_user(insn, (u32 __user *) pc) != -EFAULT) {