From: Anton Blanchard <anton@samba.org>
Subject: powerpc/perf: Always use pt_regs for userspace samples
Git-commit: 5c093efa6f2dd07d45835be870a20ed3b05b6ef5
Patch-mainline: yes
References: bnc#796891 
	    
    At the moment we always use the SIAR if the PMU supports continuous
    sampling. Unfortunately the SIAR and the PMU exception are not
    synchronised for non marked events so we can end up with callchains
    that dont make sense.
    
   The following patch checks the HV and PR bits for samples coming from
   userspace and always uses pt_regs for them. Userspace will never have
    interrupts off so there is no real advantage to using the SIAR for
    non marked events in userspace.
    
    I had experimented with a patch that did a similar thing for kernel
    samples but we lost a significant amount of information. I was
    unable to profile any of our early exception code for example.
	    
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Torsten Duwe <duwe@suse.de>

Index: linux-3.0.53-83/arch/powerpc/kernel/perf_event.c
===================================================================
--- linux-3.0.53-83.orig/arch/powerpc/kernel/perf_event.c
+++ linux-3.0.53-83/arch/powerpc/kernel/perf_event.c
@@ -201,9 +201,30 @@ static inline void perf_read_regs(struct
 	int marked = mmcra & MMCRA_SAMPLE_ENABLE;
 	int use_siar;
 
+	/*
+	 * If this isn't a PMU exception (eg a software event) the SIAR is
+	 * not valid. Use pt_regs.
+	 *
+	 * If it is a marked event use the SIAR.
+	 *
+	 * If the PMU doesn't update the SIAR for non marked events use
+	 * pt_regs.
+	 *
+	 * If the PMU has HV/PR flags then check to see if they
+	 * place the exception in userspace. If so, use pt_regs. In
+	 * continuous sampling mode the SIAR and the PMU exception are
+	 * not synchronised, so they may be many instructions apart.
+	 * This can result in confusing backtraces. We still want
+	 * hypervisor samples as well as samples in the kernel with
+	 * interrupts off hence the userspace check.
+	 */
 	if (TRAP(regs) != 0xf00)
 		use_siar = 0;
-	else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked)
+	else if (marked)
+		use_siar = 1;
+	else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING))
+		use_siar = 0;
+	else if (!(ppmu->flags & PPMU_NO_SIPR) && mmcra_sipr(mmcra))
 		use_siar = 0;
 	else
 		use_siar = 1;
