powerpc: Print MSR TM bits in oops messages
authorMichael Neuling <mikey@neuling.org>
Fri, 20 Nov 2015 04:15:32 +0000 (15:15 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 14 Dec 2015 09:40:26 +0000 (20:40 +1100)
Print MSR TM bits in oops messages.  This appends them to the end
like this:

    MSR: 8000000502823031 <SF,VEC,VSX,FP,ME,IR,DR,LE,TM[TE]>

You get the TM[] only if at least one TM MSR bit is set.  Inside the
TM[], E means Enabled (bit 32), S means Suspended (bit 33), and T
means Transactional (bit 34)

If no bits are set, you get no TM[] output.

Include rework of printbits() to handle this case.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/process.c

index 6f76f25c3ee8b5c9acaf6e42cbfe677456ce6c28..ab9373bfabdae688c936f2303de329884cb33bfe 100644 (file)
@@ -1033,10 +1033,12 @@ static void show_instructions(struct pt_regs *regs)
        printk("\n");
 }
 
-static struct regbit {
+struct regbit {
        unsigned long bit;
        const char *name;
-} msr_bits[] = {
+};
+
+static struct regbit msr_bits[] = {
 #if defined(CONFIG_PPC64) && !defined(CONFIG_BOOKE)
        {MSR_SF,        "SF"},
        {MSR_HV,        "HV"},
@@ -1066,16 +1068,49 @@ static struct regbit {
        {0,             NULL}
 };
 
-static void printbits(unsigned long val, struct regbit *bits)
+static void print_bits(unsigned long val, struct regbit *bits, const char *sep)
 {
-       const char *sep = "";
+       const char *s = "";
 
-       printk("<");
        for (; bits->bit; ++bits)
                if (val & bits->bit) {
-                       printk("%s%s", sep, bits->name);
-                       sep = ",";
+                       printk("%s%s", s, bits->name);
+                       s = sep;
                }
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+static struct regbit msr_tm_bits[] = {
+       {MSR_TS_T,      "T"},
+       {MSR_TS_S,      "S"},
+       {MSR_TM,        "E"},
+       {0,             NULL}
+};
+
+static void print_tm_bits(unsigned long val)
+{
+/*
+ * This only prints something if at least one of the TM bit is set.
+ * Inside the TM[], the output means:
+ *   E: Enabled                (bit 32)
+ *   S: Suspended      (bit 33)
+ *   T: Transactional  (bit 34)
+ */
+       if (val & (MSR_TM | MSR_TS_S | MSR_TS_T)) {
+               printk(",TM[");
+               print_bits(val, msr_tm_bits, "");
+               printk("]");
+       }
+}
+#else
+static void print_tm_bits(unsigned long val) {}
+#endif
+
+static void print_msr_bits(unsigned long val)
+{
+       printk("<");
+       print_bits(val, msr_bits, ",");
+       print_tm_bits(val);
        printk(">");
 }
 
@@ -1100,7 +1135,7 @@ void show_regs(struct pt_regs * regs)
        printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
               regs, regs->trap, print_tainted(), init_utsname()->release);
        printk("MSR: "REG" ", regs->msr);
-       printbits(regs->msr, msr_bits);
+       print_msr_bits(regs->msr);
        printk("  CR: %08lx  XER: %08lx\n", regs->ccr, regs->xer);
        trap = TRAP(regs);
        if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))