aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/perf_event.h5
-rw-r--r--arch/powerpc/perf/core-book3s.c47
2 files changed, 30 insertions, 22 deletions
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
index 5c16b891d501..0bb23725b1e7 100644
--- a/arch/powerpc/include/asm/perf_event.h
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -26,8 +26,13 @@
26#include <asm/ptrace.h> 26#include <asm/ptrace.h>
27#include <asm/reg.h> 27#include <asm/reg.h>
28 28
29/*
30 * Overload regs->result to specify whether we should use the MSR (result
31 * is zero) or the SIAR (result is non zero).
32 */
29#define perf_arch_fetch_caller_regs(regs, __ip) \ 33#define perf_arch_fetch_caller_regs(regs, __ip) \
30 do { \ 34 do { \
35 (regs)->result = 0; \
31 (regs)->nip = __ip; \ 36 (regs)->nip = __ip; \
32 (regs)->gpr[1] = *(unsigned long *)__get_SP(); \ 37 (regs)->gpr[1] = *(unsigned long *)__get_SP(); \
33 asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \ 38 asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 1818f636b9ae..dcb6a798f111 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
73{ 73{
74 return 0; 74 return 0;
75} 75}
76static inline void perf_read_regs(struct pt_regs *regs) { } 76static inline void perf_read_regs(struct pt_regs *regs)
77{
78 regs->result = 0;
79}
77static inline int perf_intr_is_nmi(struct pt_regs *regs) 80static inline int perf_intr_is_nmi(struct pt_regs *regs)
78{ 81{
79 return 0; 82 return 0;
@@ -148,17 +151,9 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs)
148static inline u32 perf_get_misc_flags(struct pt_regs *regs) 151static inline u32 perf_get_misc_flags(struct pt_regs *regs)
149{ 152{
150 unsigned long mmcra = regs->dsisr; 153 unsigned long mmcra = regs->dsisr;
154 unsigned long use_siar = regs->result;
151 155
152 /* Not a PMU interrupt: Make up flags from regs->msr */ 156 if (!use_siar)
153 if (TRAP(regs) != 0xf00)
154 return perf_flags_from_msr(regs);
155
156 /*
157 * If we don't support continuous sampling and this
158 * is not a marked event, same deal
159 */
160 if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
161 !(mmcra & MMCRA_SAMPLE_ENABLE))
162 return perf_flags_from_msr(regs); 157 return perf_flags_from_msr(regs);
163 158
164 /* 159 /*
@@ -185,10 +180,24 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
185/* 180/*
186 * Overload regs->dsisr to store MMCRA so we only need to read it once 181 * Overload regs->dsisr to store MMCRA so we only need to read it once
187 * on each interrupt. 182 * on each interrupt.
183 * Overload regs->result to specify whether we should use the MSR (result
184 * is zero) or the SIAR (result is non zero).
188 */ 185 */
189static inline void perf_read_regs(struct pt_regs *regs) 186static inline void perf_read_regs(struct pt_regs *regs)
190{ 187{
191 regs->dsisr = mfspr(SPRN_MMCRA); 188 unsigned long mmcra = mfspr(SPRN_MMCRA);
189 int marked = mmcra & MMCRA_SAMPLE_ENABLE;
190 int use_siar;
191
192 if (TRAP(regs) != 0xf00)
193 use_siar = 0;
194 else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked)
195 use_siar = 0;
196 else
197 use_siar = 1;
198
199 regs->dsisr = mmcra;
200 regs->result = use_siar;
192} 201}
193 202
194/* 203/*
@@ -1342,18 +1351,12 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
1342 */ 1351 */
1343unsigned long perf_instruction_pointer(struct pt_regs *regs) 1352unsigned long perf_instruction_pointer(struct pt_regs *regs)
1344{ 1353{
1345 unsigned long mmcra = regs->dsisr; 1354 unsigned long use_siar = regs->result;
1346 1355
1347 /* Not a PMU interrupt */ 1356 if (use_siar)
1348 if (TRAP(regs) != 0xf00) 1357 return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
1349 return regs->nip; 1358 else
1350
1351 /* Processor doesn't support sampling non marked events */
1352 if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
1353 !(mmcra & MMCRA_SAMPLE_ENABLE))
1354 return regs->nip; 1359 return regs->nip;
1355
1356 return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
1357} 1360}
1358 1361
1359static bool pmc_overflow(unsigned long val) 1362static bool pmc_overflow(unsigned long val)