Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -26,8 +26,13 @@
#include <asm/ptrace.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)			\
	do {							\
		(regs)->result = 0;				\
		(regs)->nip = __ip;				\
		(regs)->gpr[1] = *(unsigned long *)__get_SP();	\
		asm volatile("mfmsr %0" : "=r" ((regs)->msr));	\
+25 −22
Original line number Diff line number Diff line
@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
	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)
{
	return 0;
@@ -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)
{
	unsigned long mmcra = regs->dsisr;
	unsigned long use_siar = regs->result;

	/* Not a PMU interrupt: Make up flags from regs->msr */
	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))
	if (!use_siar)
		return perf_flags_from_msr(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
 * 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)
{
	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)
 */
unsigned long perf_instruction_pointer(struct pt_regs *regs)
{
	unsigned long mmcra = regs->dsisr;

	/* Not a PMU interrupt */
	if (TRAP(regs) != 0xf00)
		return regs->nip;

	/* Processor doesn't support sampling non marked events */
	if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) &&
	    !(mmcra & MMCRA_SAMPLE_ENABLE))
		return regs->nip;
	unsigned long use_siar = regs->result;

	if (use_siar)
		return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
	else
		return regs->nip;
}

static bool pmc_overflow(unsigned long val)