powerpc/perf: Add kernel support for new MSR[HV PR] bits in trace-imc
authorAnju T Sudhakar <anju@linux.vnet.ibm.com>
Mon, 13 Jul 2020 14:46:23 +0000 (20:16 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 16 Jul 2020 03:12:46 +0000 (13:12 +1000)
IMC trace-mode record has MSR[HV PR] bits added in the third DW.
These bits can be used to set the cpumode for the instruction pointer
captured in each sample.

Add support in kernel to use these bits to set the cpumode for
each sample.

Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200713144623.508695-1-maddy@linux.ibm.com
arch/powerpc/include/asm/imc-pmu.h
arch/powerpc/perf/imc-pmu.c

index 4da4fcba0684bba76dc000009abfe25f54286ec1..4f897993b7107537c25483df2d5cfd8613a4bd81 100644 (file)
@@ -99,6 +99,11 @@ struct trace_imc_data {
  */
 #define IMC_TRACE_RECORD_TB1_MASK      0x3ffffffffffULL
 
+/*
+ * Bit 0:1 in third DW of IMC trace record
+ * specifies the MSR[HV PR] values.
+ */
+#define IMC_TRACE_RECORD_VAL_HVPR(x)   ((x) >> 62)
 
 /*
  * Device tree parser code detects IMC pmu support and
index 0edcfd0b491d9892d5df6ff8f57f015dc88436dd..a45d694a5d5d88814ec13bb2d76ec12cc6e4af82 100644 (file)
@@ -1288,11 +1288,30 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem,
        header->size = sizeof(*header) + event->header_size;
        header->misc = 0;
 
-       if (is_kernel_addr(data->ip))
-               header->misc |= PERF_RECORD_MISC_KERNEL;
-       else
-               header->misc |= PERF_RECORD_MISC_USER;
-
+       if (cpu_has_feature(CPU_FTR_ARCH_31)) {
+               switch (IMC_TRACE_RECORD_VAL_HVPR(mem->val)) {
+               case 0:/* when MSR HV and PR not set in the trace-record */
+                       header->misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+                       break;
+               case 1: /* MSR HV is 0 and PR is 1 */
+                       header->misc |= PERF_RECORD_MISC_GUEST_USER;
+                       break;
+               case 2: /* MSR HV is 1 and PR is 0 */
+                       header->misc |= PERF_RECORD_MISC_HYPERVISOR;
+                       break;
+               case 3: /* MSR HV is 1 and PR is 1 */
+                       header->misc |= PERF_RECORD_MISC_USER;
+                       break;
+               default:
+                       pr_info("IMC: Unable to set the flag based on MSR bits\n");
+                       break;
+               }
+       } else {
+               if (is_kernel_addr(data->ip))
+                       header->misc |= PERF_RECORD_MISC_KERNEL;
+               else
+                       header->misc |= PERF_RECORD_MISC_USER;
+       }
        perf_event_header__init_id(header, data, event);
 
        return 0;