Commit 75382aa7 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt

powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs

The logic to choose whether to use the SIAR or get the information
out of pt_regs is going to get more complicated, so do it once in
perf_read_regs.

We overload regs->result which is gross but we are already doing it
with regs->dsisr.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 68b30bb9
...@@ -26,8 +26,13 @@ ...@@ -26,8 +26,13 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/reg.h> #include <asm/reg.h>
/*
* Overload regs->result to specify whether we should use the MSR (result
* is zero) or the SIAR (result is non zero).
*/
#define perf_arch_fetch_caller_regs(regs, __ip) \ #define perf_arch_fetch_caller_regs(regs, __ip) \
do { \ do { \
(regs)->result = 0; \
(regs)->nip = __ip; \ (regs)->nip = __ip; \
(regs)->gpr[1] = *(unsigned long *)__get_SP(); \ (regs)->gpr[1] = *(unsigned long *)__get_SP(); \
asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \ asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \
......
...@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) ...@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{ {
return 0; return 0;
} }
static inline void perf_read_regs(struct pt_regs *regs) { } static inline void perf_read_regs(struct pt_regs *regs)
{
regs->result = 0;
}
static inline int perf_intr_is_nmi(struct pt_regs *regs) static inline int perf_intr_is_nmi(struct pt_regs *regs)
{ {
return 0; return 0;
...@@ -148,17 +151,9 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs) ...@@ -148,17 +151,9 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs)
static inline u32 perf_get_misc_flags(struct pt_regs *regs) static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{ {
unsigned long mmcra = regs->dsisr; unsigned long mmcra = regs->dsisr;
unsigned long use_siar = regs->result;
/* Not a PMU interrupt: Make up flags from regs->msr */ if (!use_siar)
if (TRAP(regs) != 0xf00)
return perf_flags_from_msr(regs);
/*
* If we don't support continuous sampling and this
* is not a marked event, same deal
*/
if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
!(mmcra & MMCRA_SAMPLE_ENABLE))
return perf_flags_from_msr(regs); return perf_flags_from_msr(regs);
/* /*
...@@ -185,10 +180,24 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) ...@@ -185,10 +180,24 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
/* /*
* Overload regs->dsisr to store MMCRA so we only need to read it once * Overload regs->dsisr to store MMCRA so we only need to read it once
* on each interrupt. * on each interrupt.
* Overload regs->result to specify whether we should use the MSR (result
* is zero) or the SIAR (result is non zero).
*/ */
static inline void perf_read_regs(struct pt_regs *regs) static inline void perf_read_regs(struct pt_regs *regs)
{ {
regs->dsisr = mfspr(SPRN_MMCRA); unsigned long mmcra = mfspr(SPRN_MMCRA);
int marked = mmcra & MMCRA_SAMPLE_ENABLE;
int use_siar;
if (TRAP(regs) != 0xf00)
use_siar = 0;
else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked)
use_siar = 0;
else
use_siar = 1;
regs->dsisr = mmcra;
regs->result = use_siar;
} }
/* /*
...@@ -1342,18 +1351,12 @@ unsigned long perf_misc_flags(struct pt_regs *regs) ...@@ -1342,18 +1351,12 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
*/ */
unsigned long perf_instruction_pointer(struct pt_regs *regs) unsigned long perf_instruction_pointer(struct pt_regs *regs)
{ {
unsigned long mmcra = regs->dsisr; unsigned long use_siar = regs->result;
/* Not a PMU interrupt */ if (use_siar)
if (TRAP(regs) != 0xf00) return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
return regs->nip; else
/* Processor doesn't support sampling non marked events */
if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
!(mmcra & MMCRA_SAMPLE_ENABLE))
return regs->nip; return regs->nip;
return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
} }
static bool pmc_overflow(unsigned long val) static bool pmc_overflow(unsigned long val)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment