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