aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2009-10-27 14:46:55 -0400
committerPaul Mackerras <paulus@samba.org>2009-10-28 01:13:03 -0400
commiteecff81d1fcda22cd0029d11fe2a71dceed11dad (patch)
tree9cbccbfc76a7336aa1d309b89407e31a76110784 /arch
parentf7d7986060b2890fc26db6ab5203efbd33aa2497 (diff)
powerpc: Create PPC_WARN_ALIGNMENT to match PPC_WARN_EMULATED
perf_event wants a separate event for alignment and emulation faults, so create another emulation event. This will make it easy to hook in perf_event at one spot. We pass in regs which will be required for these events. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/emulated_ops.h7
-rw-r--r--arch/powerpc/kernel/align.c12
-rw-r--r--arch/powerpc/kernel/traps.c18
3 files changed, 20 insertions, 17 deletions
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
index 9154e8526732..640c4e456aa5 100644
--- a/arch/powerpc/include/asm/emulated_ops.h
+++ b/arch/powerpc/include/asm/emulated_ops.h
@@ -57,7 +57,7 @@ extern u32 ppc_warn_emulated;
57 57
58extern void ppc_warn_emulated_print(const char *type); 58extern void ppc_warn_emulated_print(const char *type);
59 59
60#define PPC_WARN_EMULATED(type) \ 60#define __PPC_WARN_EMULATED(type) \
61 do { \ 61 do { \
62 atomic_inc(&ppc_emulated.type.val); \ 62 atomic_inc(&ppc_emulated.type.val); \
63 if (ppc_warn_emulated) \ 63 if (ppc_warn_emulated) \
@@ -66,8 +66,11 @@ extern void ppc_warn_emulated_print(const char *type);
66 66
67#else /* !CONFIG_PPC_EMULATED_STATS */ 67#else /* !CONFIG_PPC_EMULATED_STATS */
68 68
69#define PPC_WARN_EMULATED(type) do { } while (0) 69#define __PPC_WARN_EMULATED(type) do { } while (0)
70 70
71#endif /* !CONFIG_PPC_EMULATED_STATS */ 71#endif /* !CONFIG_PPC_EMULATED_STATS */
72 72
73#define PPC_WARN_EMULATED(type, regs) __PPC_WARN_EMULATED(type)
74#define PPC_WARN_ALIGNMENT(type, regs) __PPC_WARN_EMULATED(type)
75
73#endif /* _ASM_POWERPC_EMULATED_OPS_H */ 76#endif /* _ASM_POWERPC_EMULATED_OPS_H */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a5b632e52fae..3839839f83c7 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -732,7 +732,7 @@ int fix_alignment(struct pt_regs *regs)
732 732
733#ifdef CONFIG_SPE 733#ifdef CONFIG_SPE
734 if ((instr >> 26) == 0x4) { 734 if ((instr >> 26) == 0x4) {
735 PPC_WARN_EMULATED(spe); 735 PPC_WARN_ALIGNMENT(spe, regs);
736 return emulate_spe(regs, reg, instr); 736 return emulate_spe(regs, reg, instr);
737 } 737 }
738#endif 738#endif
@@ -786,7 +786,7 @@ int fix_alignment(struct pt_regs *regs)
786 flags |= SPLT; 786 flags |= SPLT;
787 nb = 8; 787 nb = 8;
788 } 788 }
789 PPC_WARN_EMULATED(vsx); 789 PPC_WARN_ALIGNMENT(vsx, regs);
790 return emulate_vsx(addr, reg, areg, regs, flags, nb); 790 return emulate_vsx(addr, reg, areg, regs, flags, nb);
791 } 791 }
792#endif 792#endif
@@ -794,7 +794,7 @@ int fix_alignment(struct pt_regs *regs)
794 * the exception of DCBZ which is handled as a special case here 794 * the exception of DCBZ which is handled as a special case here
795 */ 795 */
796 if (instr == DCBZ) { 796 if (instr == DCBZ) {
797 PPC_WARN_EMULATED(dcbz); 797 PPC_WARN_ALIGNMENT(dcbz, regs);
798 return emulate_dcbz(regs, addr); 798 return emulate_dcbz(regs, addr);
799 } 799 }
800 if (unlikely(nb == 0)) 800 if (unlikely(nb == 0))
@@ -804,7 +804,7 @@ int fix_alignment(struct pt_regs *regs)
804 * function 804 * function
805 */ 805 */
806 if (flags & M) { 806 if (flags & M) {
807 PPC_WARN_EMULATED(multiple); 807 PPC_WARN_ALIGNMENT(multiple, regs);
808 return emulate_multiple(regs, addr, reg, nb, 808 return emulate_multiple(regs, addr, reg, nb,
809 flags, instr, swiz); 809 flags, instr, swiz);
810 } 810 }
@@ -825,11 +825,11 @@ int fix_alignment(struct pt_regs *regs)
825 825
826 /* Special case for 16-byte FP loads and stores */ 826 /* Special case for 16-byte FP loads and stores */
827 if (nb == 16) { 827 if (nb == 16) {
828 PPC_WARN_EMULATED(fp_pair); 828 PPC_WARN_ALIGNMENT(fp_pair, regs);
829 return emulate_fp_pair(addr, reg, flags); 829 return emulate_fp_pair(addr, reg, flags);
830 } 830 }
831 831
832 PPC_WARN_EMULATED(unaligned); 832 PPC_WARN_ALIGNMENT(unaligned, regs);
833 833
834 /* If we are loading, get the data from user space, else 834 /* If we are loading, get the data from user space, else
835 * get it from register values 835 * get it from register values
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6f0ae1a9bfae..9d1f9354d6ca 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -759,7 +759,7 @@ static int emulate_instruction(struct pt_regs *regs)
759 759
760 /* Emulate the mfspr rD, PVR. */ 760 /* Emulate the mfspr rD, PVR. */
761 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { 761 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
762 PPC_WARN_EMULATED(mfpvr); 762 PPC_WARN_EMULATED(mfpvr, regs);
763 rd = (instword >> 21) & 0x1f; 763 rd = (instword >> 21) & 0x1f;
764 regs->gpr[rd] = mfspr(SPRN_PVR); 764 regs->gpr[rd] = mfspr(SPRN_PVR);
765 return 0; 765 return 0;
@@ -767,7 +767,7 @@ static int emulate_instruction(struct pt_regs *regs)
767 767
768 /* Emulating the dcba insn is just a no-op. */ 768 /* Emulating the dcba insn is just a no-op. */
769 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) { 769 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
770 PPC_WARN_EMULATED(dcba); 770 PPC_WARN_EMULATED(dcba, regs);
771 return 0; 771 return 0;
772 } 772 }
773 773
@@ -776,7 +776,7 @@ static int emulate_instruction(struct pt_regs *regs)
776 int shift = (instword >> 21) & 0x1c; 776 int shift = (instword >> 21) & 0x1c;
777 unsigned long msk = 0xf0000000UL >> shift; 777 unsigned long msk = 0xf0000000UL >> shift;
778 778
779 PPC_WARN_EMULATED(mcrxr); 779 PPC_WARN_EMULATED(mcrxr, regs);
780 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); 780 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
781 regs->xer &= ~0xf0000000UL; 781 regs->xer &= ~0xf0000000UL;
782 return 0; 782 return 0;
@@ -784,19 +784,19 @@ static int emulate_instruction(struct pt_regs *regs)
784 784
785 /* Emulate load/store string insn. */ 785 /* Emulate load/store string insn. */
786 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { 786 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
787 PPC_WARN_EMULATED(string); 787 PPC_WARN_EMULATED(string, regs);
788 return emulate_string_inst(regs, instword); 788 return emulate_string_inst(regs, instword);
789 } 789 }
790 790
791 /* Emulate the popcntb (Population Count Bytes) instruction. */ 791 /* Emulate the popcntb (Population Count Bytes) instruction. */
792 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { 792 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
793 PPC_WARN_EMULATED(popcntb); 793 PPC_WARN_EMULATED(popcntb, regs);
794 return emulate_popcntb_inst(regs, instword); 794 return emulate_popcntb_inst(regs, instword);
795 } 795 }
796 796
797 /* Emulate isel (Integer Select) instruction */ 797 /* Emulate isel (Integer Select) instruction */
798 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { 798 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
799 PPC_WARN_EMULATED(isel); 799 PPC_WARN_EMULATED(isel, regs);
800 return emulate_isel(regs, instword); 800 return emulate_isel(regs, instword);
801 } 801 }
802 802
@@ -995,7 +995,7 @@ void SoftwareEmulation(struct pt_regs *regs)
995#ifdef CONFIG_MATH_EMULATION 995#ifdef CONFIG_MATH_EMULATION
996 errcode = do_mathemu(regs); 996 errcode = do_mathemu(regs);
997 if (errcode >= 0) 997 if (errcode >= 0)
998 PPC_WARN_EMULATED(math); 998 PPC_WARN_EMULATED(math, regs);
999 999
1000 switch (errcode) { 1000 switch (errcode) {
1001 case 0: 1001 case 0:
@@ -1018,7 +1018,7 @@ void SoftwareEmulation(struct pt_regs *regs)
1018#elif defined(CONFIG_8XX_MINIMAL_FPEMU) 1018#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
1019 errcode = Soft_emulate_8xx(regs); 1019 errcode = Soft_emulate_8xx(regs);
1020 if (errcode >= 0) 1020 if (errcode >= 0)
1021 PPC_WARN_EMULATED(8xx); 1021 PPC_WARN_EMULATED(8xx, regs);
1022 1022
1023 switch (errcode) { 1023 switch (errcode) {
1024 case 0: 1024 case 0:
@@ -1129,7 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
1129 1129
1130 flush_altivec_to_thread(current); 1130 flush_altivec_to_thread(current);
1131 1131
1132 PPC_WARN_EMULATED(altivec); 1132 PPC_WARN_EMULATED(altivec, regs);
1133 err = emulate_altivec(regs); 1133 err = emulate_altivec(regs);
1134 if (err == 0) { 1134 if (err == 0) {
1135 regs->nip += 4; /* skip emulated instruction */ 1135 regs->nip += 4; /* skip emulated instruction */